home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1995 November
/
EnigmA AMIGA RUN 02 (1995)(G.R. Edizioni)(IT)[!][issue 1995-11][Skylink CD].iso
/
earcd
/
misc
/
sexehead.lha
/
SEXeHeader.asm
< prev
next >
Wrap
Assembly Source File
|
1995-09-24
|
97KB
|
2,804 lines
** EXEHeader.asm 22/9/95
**
** © 1995 Soyeb Aswat and NKH Software
**
** Freeware
**
*******************************************************************************************************
*
* Microsoft Windows New Executable 'NE' Examination utility
*
*******************************************************************************************************
**
** Open dos.library
** If open failed then
** Print error message
** Return
** Open file
** If open failed then
** Print error message
** Close dos.library
** Return
** Seek to $18
**
** If (Current file pos word) < $40 then ; Test if windows prog
** Close file
** Close dos.library
** Return
**
** Seek to $3C ; Goto start of win header
** Get word value
** Seek to word value above
**
** If (Current file pos word) <> 'NE' then ; Test if windows NE file
** Close file
** Close dos.library
** Return
**
** ; Header length HeaderLen=(offset $20)+(Offset $20)-(WinHead)
** ; WinHead=Start of windows header
** Allocate HeaderLen memory ; Read in header
** Seek to WinHead
** Read HeaderLen bytes into buffer
**
** Print module name
** Get address of resident-name table
** Print first entry
** Print module description
** Get address of non-resident name table
** Print first entry
** Print linker version number (HEX)
** Print linker revision number (HEX)
** Print $0C flags data
** Get word at $0C
** If bit 0 set then SINGLE DATA
** If bit 1 set then MULTIPLEDATA
** else NOAUTODATA
** If bit 11 set then self loading executable
** If bit 15 set then file is a library module
** Print automatic data segment number
** If 0 then print NOAUTODATA
** else print segment number
** Print local heap size
** If 0 then print No local allocation
** else print heap size
** Print initial stack size
** Print CS:IP
** Print SS:SP
** If SP=0 and DS=SS then SP= stacksize + data segment size (data seg size is in seg table)
** else print SS:SP as normal
**
** Print offset to start of segment table
** Print number of entries in segment table
** Print contents of segment table
** n=number of entries in segment table
** REPEAT
** Print segment number
** Check offset 0 of each entry and
** If 0 then print "No data provided for this segment"
** else print size of segment in file
** Print minimum allocation for this segment offset 6
** Print flag meanings
** Print "Segment type"
** If bit 0 set then print DATA
** else print CODE
** If bit 1 set then print "Loader allocates memory for segment"
** If bit 2 set then print "Segment is loaded at load time"
** Print "Segment relocation"
** If bit 4 set then print "MOVEABLE"
** else print "FIXED"
** Print "Segment sharing"
** If bit 5 set then print "PURE or SHAREABLE"
** else print "IMPURE or NONSHAREABLE"
** Print "Segment load type"
** If bit 6 set then print "PRELOAD"
** else print "LOADONCALL"
** If bit 7 set then
** Print "Access type"
** If bit 0 set then print "READONLY"
** else print "EXECUTEONLY"
** If bit 8 set then print "Segment contains relocation data"
** If bit 12 set then print "Segment is discardable"
** Decrement n
** UNTIL n=0
**
** Print offset to resource table
** Print contents of resource table
** Print rscAlignShift
** Print rscTypes
** REPEAT
** Print rtTypeID
** If rtTypeID < $8000 then
** n=( rtTypeID + resource table base )
** Print n chars from above address+1
** If rtTypeID = $8000 + 1 then print "RT_CURSOR"
** If rtTypeID = $8000 + 2 then print "RT_BITMAP"
** If rtTypeID = $8000 + 3 then print "RT_ICON"
** If rtTypeID = $8000 + 4 then print "RT_MENU"
** If rtTypeID = $8000 + 5 then print "RT_DIALOG"
** If rtTypeID = $8000 + 6 then print "RT_STRING"
** If rtTypeID = $8000 + 7 then print "RT_FONTDIR"
** If rtTypeID = $8000 + 8 then print "RT_FONT"
** If rtTypeID = $8000 + 9 then print "RT_ACCELERATOR"
** If rtTypeID = $8000 + 10 then print "RT_RCDATA"
** If rtTypeID = $8000 + 12 then print "RT_GROUP_CURSOR"
** If rtTypeID = $8000 + 14 then print "RT_GROUP_ICON"
** If rtTypeID = $8000 + 16 then print "Version info?"
** ELSE Print "Unknown resource type",rtTypeID
** Print rtResourceCount
** Skip rtReserved (word)
** FOR n=1 to rtResourceCount
** Print rtNameInfo
** Print rnOffset
** Print rnLength
** Print rnFlags
** If bit 4 set then print "MOVEABLE"
** If bit 5 set then print "PURE"
** If bit 6 set then print "PRELOAD"
** Print rnID
** If rnID >= $8000 then print rnID-$8000
** ELSE
** n=( rnID + resource table base )
** Print n chars from above address+1
** Skip rnHandle (word)
** Skip rnUsage (word)
** END ; FOR
** UNTIL rscEndTypes ; ie. next byte = 0 ; REPEAT for printing rscTypes
**
** Print resident-name table
** Get address of resident-name table
** Skip first entry
** Get length of string
** Add to pointer
** Add 2 to pointer to skip ordinal
** WHILE next byte !=
** Get length of string
** Skip pointer past string
** Print string
** Print ordinal
** END ; WHILE
**
** Print module-reference and imported-name tables
** Print number of entries in module-reference table
** Get address of imported-name table
** FOR n=1 to number of entries in module-reference table
** Get length of string
** Get address of string
** Print string
** END ; FOR
**
** Print entry table
** Test length of entry table
** If length != 0 then
** Get address of entry table
** REPEAT
** Get number of entries in bundle
** Get bundle type
** Add 2 to pointer
** If bundle type = 0 then ; Null entry
** Print "Null entries : ",entries
** Add entries to entry counter.
** If bundle type = $FE then ; Constant pointer
** Print "Constant pointer"
** FOR n=1 to entries in bundle
** Print "Entry ",entry counter
** Print "Offset : ",EntryConstValue
** If bit 0 of EntryFixFlags = 1 then
** Print " Exported "
** If bit 1 of EntryFixFlags = 1 then
** Print "SINGLEDATA"
** Add 3 to pointer
** END ; FOR
** If bundle type = $FF then ; Movable segment
** Print "Movable segment records : ",entries in bundle," entries."
** FOR n=1 to entries in bundle
** Print "Entry ",entry counter
** Print "Segment : ",EntryMoveSegment
** Print "Offset : ",EntryMoveOffset
** If bit 0 of EntryMoveFlags = 1 then
** Print " Exported "
** If bit 1 of EntryMoveFlags = 1 then
** Print " Global"
** Add 6 to pointer
** END ; FOR
** ELSE ; Fixed segment
** Print "Fixed segment records : ",entries in bundle," entries. Segment : ",bundle type
** FOR n=1 to entries in bundle
** Print "Entry ",entry counter
** Print "Offset : ",EntryFixOffset
** If bit 0 of EntryFixFlags = 1 then
** Print " Exported "
** If bit 1 of EntryFixFlags = 1 then
** Print "SINGLEDATA"
** Add 3 to pointer
** END ; FOR
** UNTIL next byte = 0
**
** Print segment relocations
** Print "Segment relocations"
** Initialize segment counter
** Get address of segment table
** Get number of entries in segment table
** FOR n = 1 to entries in segment table
** If this segment contains relocation data then
** Print "Relocations for segment ",segment counter
** Goto position of segment in file
** Move an extra segment length bytes
** Get intel word at that address (items in table)
** Allocate items in table * 8 bytes of ram
** If allocation UNsuccesful then
** Print "Out of memory"
** rts
** Read items in table * 8 bytes into allocated buffer
** If read failed then
** Print "Read from file failed!"
** rts
** Print "type offset target"
** FOR x = 1 to items in table
** If RelocAddrType = 0 then
** Print "LoByte "
** If RelocAddrType = 2 then
** Print "Select "
** If RelocAddrType = 3 then
** Print "PTR "
** If RelocAddrType = 5 then
** Print "OFFS "
** If RelocAddrType = 11 then
** Print "PTR-48 "
** If RelocAddrType = 13 then
** Print "OFFS-32 "
** else print "Unknown relocation type. Send me this file to df114@city.ac.uk read docs!!!!"
** rts
**
** Print RelocOffset
** If RelocType = 0 then ; Internal reference
** If RelocB4 = $FF then
** Print "Entry ",RelocB6
** else
** Print RelocB4,":",RelocB6 ; Segment:Offset are the wrong way round!
** If RelocType = 1 then ; Imported ordinal
** (RelocB4 - 1)*2
** Add offset to mod-ref table
** Add that word to offset of imp-name table
** Print that byte many bytes at that addr+1
** Print ".",RelocB6
** If RelocType = 2 then ; Imported name
** (RelocB4 - 1)*2
** Add offset to mod-ref table
** Add that word to offset of imp-name table
** Print that byte many bytes at that addr+1
** Print "."
** RelocB6 + offset to imp-name table
** Print that byte many bytes at that addr+1
** If RelocType = 3 then ; OSFIXUP
** Print "OSFIXUP Send me this file to df114@city.ac.uk read docs!!!!"
** rts
** If RelocType = 5 then ; Additive?
** (RelocB4 - 1)*2
** Add offset to mod-ref table
** Add that word to offset of imp-name table
** Print that byte many bytes at that addr+1
** Print ".",RelocB6
** else
** Print "Unknown relocation type send me this file to df114@city.ac.uk read docs!!!!"
**
** Add 8 to pointer ; Skip to next entry in relocation table
** END ; FOR
** Deallocate memory just used
** Add 8 to pointer' ; Skip to next entry in segment table
** END ; FOR
** Close file
** Close dos.library
** Return
INCLUDE work:languages/devpac/system
; INCLUDE "work:languages/devpac/amiga.lib.inc"
; INCLUDE "exec/exec.i"
; INCLUDE "dos/dos.i"
; INCLUDE "work:languages/devpac/examples/misc/easystart.i"
; XREF _LVOReadArgs()
AbsExecBase EQU 4
AnyMemoryType EQU 0
NewLine EQU 10
NULL EQU 0
** Locations in the file
AutoDataSegNum EQU $0E
DataOffset EQU $00
DosHeaderValid EQU $18
EntryBndlNum EQU $00 ; Entry table Number of entries in this bundle
EntryBndlTyp EQU $01 ; Bundle type
EntryConstFlags EQU $00 ; Offset to flags for entry type constant
EntryConstValue EQU $01 ; Offset to value for entry type constant
EntryFixFlags EQU $00 ; Flags for fixed segment
EntryFixOffset EQU $01 ; Offset for fixed segment
EntryLength EQU $06 ; Length of entry table in entries (in windows header)
EntryMoveFlags EQU $00 ; Flags for movable segment
EntryMoveOffset EQU $04 ; Offset for movable segment
EntryMoveSeg EQU $03 ; Segment number for movable segment
EntryOffset EQU $04 ; Offset to entry table relative to start of windows header
FileFlags EQU $0C
FileSegLength EQU $02
ImpTableOffset EQU $2A
ImpNameOffset EQU $2A
InitCSIP EQU $14
InitLocalHeap EQU $10
InitSSSP EQU $18
InitStackSize EQU $12
LinkerRevisionNum EQU $02
LinkerVersionNum EQU $03
ModRefOffset EQU $28
ModTableEntries EQU $1E
NonResNamTabOffset EQU $2C
NonResNamTableSize EQU $20
rnFlags EQU $04
rnID EQU $06
rnLength EQU $02
rnOffset EQU $00
rscAlignShift EQU $00
RelocAddrType EQU $00
RelocB4 EQU $04
RelocB6 EQU $06
RelocOffset EQU $02
RelocType EQU $01
ResNameTabOffset EQU $26
RscTableOffset EQU $24
SegAllocSize EQU $06
SegFlags EQU $04
SegmentPos EQU $00
SegmentLen EQU $02
SegTableEntryNum EQU $1C
SegTableOffset EQU $22
ShiftCount EQU $32
WinHeaderOffset EQU $3C
** Temporary storage
TempStoreSize EQU 256 ; Size of the temporary storage buffer
DosBase EQU 4*0
aFileHandle EQU 4*1
HeaderAddress EQU 4*2
HeaderLen EQU 4*3
HeaderOffset EQU 4*4
OutputHandle EQU 4*5
RelocBufferAddr EQU 4*6
RelocBufferLen EQU 4*7
StackEquation EQU 4*8
TempBufferLen EQU 4*9
UseStdIOFlag EQU 4*10
TempBuffer EQU 4*11 ; *MUST* always be last!
SECTION code,CODE
; Allocate temporary storage buffer
move.l AbsExecBase,a6 ; Get exec base address
move.l #0,d0 ; Clear
move.l #$FFFFFFFF,d1 ; All
jsr _LVOSetSignal(a6) ; Signals
move.l #TempStoreSize,d0 ; Allocate Temp store bytes of ram
move.l d0,d3 ; Save buffer length
move.l #AnyMemoryType,d1 ; Any type of memory
jsr _LVOAllocMem(a6) ; Allocate the memory
tst.l d0 ; Was memory allocated?
beq TempBufNoAlloc ; Temp buffer was not allocated
move.l d0,a5 ; Store address in a5
move.l d3,TempBufferLen(a5) ; Save length of temp buffer
; Open dos.library
move.l #37,d0 ; d0 = version 37 or above
lea DosLibName,a1 ; a0 = * "dos.library"
jsr _LVOOpenLibrary(a6) ; Open dos.library
tst.l d0 ; Did dos lib open OK?
beq DosNotOpen ; Goto dos lib not opened OK
move.l d0,DosBase(a5) ; Save dos base address
move.l d0,a6 ; Put dos base address in a6
; Get standard output handle
move.l #$FFFFFFFF,UseStdIOFlag(a5) ; Clear flag
jsr _LVOOutput(a6) ; Get standard output handle
move.l d0,OutputHandle(a5) ; Save output handle
; Read command line
lea Template,a0 ; Get address of template
move.l a0,d1 ; Put in template register
lea TempBuffer(a5),a0 ; Get address of temp buffer
move.l a0,d2 ; Put in array register
clr.l 4(a0) ; Clear the second argument
move.l #NULL,d3 ; Use Input()
jsr _LVOReadArgs(a6) ; Read the command line
move.l d0,d7 ; Save address Args
move.l d0,d1 ; Get ready for FreeArgs
tst.l d1 ; Did it fail?
bne DidNotFail ; Jump if no fail
jsr _LVOFreeArgs(a6) ; Free their memory If ReadArgs failed then quit
lea Template,a0 ; Get address of message
move.l TemplateLen,d3 ; Get length of message
bsr PrintMSG ; Print message
lea NewLineMSG,a0 ; Get address of message
move.l NewLineMSGLen,d3 ; Get length of message
bra PrintErrorAndReturnToDos; Finished
; Use stdio?
DidNotFail
tst.l TempBuffer+4(a5) ; Use stdio?
bne UseStdIO ; Jump if yes
move.l #0,UseStdIOFlag(a5) ; Clear stdio flag Open window for output
lea OutputString,a0 ; Get console name
move.l a0,d1 ; Put in right register
move.l #MODE_READWRITE,d2 ; Get mode
jsr _LVOOpen(a6) ; Open output
move.l d0,OutputHandle(a5) ; Save output handle
UseStdIO
; Open file
move.l TempBuffer(a5),d1 ; Get address of argument
move.l #MODE_OLDFILE,d2 ; Open file for reading
jsr _LVOOpen(a6) ; Open file
move.l d7,d1 ; Get Args structure
move.l d0,d7 ; Save file handle
jsr _LVOFreeArgs(a6) ; Free their memory
move.l d7,d0 ; Get file handle
tst.l d0 ; Did file open OK?
beq FileNotOpenOK ; Goto file not open error
move.l d0,aFileHandle(a5) ; Save open file handle
; Seek to is dos header a valid windows header?
move.l #DosHeaderValid,d2 ; Position to go to
bsr SeekTo ; Seek
; If (current file position word) < $40 then quit
bsr ReadIntelWord ; Read word at position
cmp.w #$40,d2 ; Is less than $40?
blt NotWindowsEXE ; Goto wrong file type error
; Seek to offset to windows header
move.l #WinHeaderOffset,d2 ; Position to go to
bsr SeekTo ; Seek there
; Get word value
bsr ReadIntelWord ; Read word at that position
clr.l d4 ; Clear scratch register
move.w d2,d4 ; d4 = offset to start of header
move.l d4,d2 ; Clear high word
move.l d2,HeaderOffset(a5) ; Save offset
; Seek to word value above
bsr SeekTo ; Seek to start of header
; If (current file pos word) <> "NE" then quit
bsr ReadIntelWord ; Get word at start of header
cmp.w #$454E,d2 ; Is it "NE"? The code $454E is "EN"
; because ReadWord reverses the bytes
bne NotWindowsEXE ; Quit if not New Executable
; HeaderLen = (bytes in non-resident name table)+(offset to non-resident name table)-(WinHeaderOffset)
move.l #NonResNamTableSize,d2 ; Offset $20
add.l d4,d2 ; Add base
bsr SeekTo ; Seek to $20
bsr ReadIntelWord ; Read word
clr.l d5 ; Clear scratch register
move.w d2,d5 ; Move ($20) to d5
move.l #NonResNamTabOffset,d2 ; Offset $2C
add.l d4,d2 ; Add base
bsr SeekTo ; Seek to $2C
bsr ReadIntelWord ; Read low word at $2C
move.w d2,d6 ; Save word
bsr ReadIntelWord ; Read high word at $2C
swap d2 ; Place high byte in correct position
move.w d6,d2 ; Construct longword
add.l d2,d5 ; d5 = (offset $20)+(offset$2C)
sub.l d4,d5 ; d5 = ($20)+($2C)-(WinHeaderOffset)
move.l d5,HeaderLen(a5) ; Store HeaderLen
; bra CloseFileAndDosLib;testing
; Allocate HeadLen bytes of memory
move.l d5,d0 ; Put HeadLen into d0
move.l #AnyMemoryType,d1 ; Any memory type
move.l AbsExecBase,a6 ; Get ExecBase
jsr _LVOAllocMem(a6) ; Allocate the memory
tst.l d0 ; Was memory allocated?
beq MemoryNotAllocated ; Goto not enough memory error
move.l d0,a4 ; Store address of allocated memory
move.l d0,HeaderAddress(a5) ; Store alloced mem addr permanantly
; Seek to start of win header
move.l DosBase(a5),a6 ; Get dos lib base address
move.l d4,d2 ; Get win header base address
bsr SeekTo ; Goto start of header
; Read above bytes into buffer
move.l aFileHandle(a5),d1 ; Get file handle
move.l a4,d2 ; Put memory block address in d2
move.l d5,d3 ; HeadLen bytes to be read
jsr _LVORead(a6) ; Read header into buffer
cmp.l d5,d0 ; Was whole header read?
bne ReadFailed ; Goto read failed
** Main section (prints everything) *******************************************************************
bsr PrintFileDetails ; Prints details about the whole file
bsr PrintSegmentTable ; Print the segment table
bsr PrintResourceTable ; Well isn't it obvious? Print resource table
bsr PrintResNameTable ; Print resident name table
bsr PrintModImpTables ; Print module-reference and imported-name tables
bsr PrintNonResNameTable ; Print non-resident name table
bsr PrintEntryTable ; Print the entry table
bsr PrintRelocTabs ; Print segment relocation tables
******************************************************************************************************
; Clean up before returning to dos
move.l AbsExecBase,a6 ; Get exec base
move.l a6,a4 ; Keep copy of exec base
move.l HeaderAddress(a5),a1 ; Get address of header
move.l HeaderLen(a5),d0 ; Get headers length
jsr _LVOFreeMem(a6) ; Free memory
lea FinishMSG,a0 ; Get address of closing message
move.l FinishMSGLen,d3 ; Get length of finish message
bra CloseFileAndDosLibPrintMSG ; Print closing message cleanup and return to dos
*******************************************************************************************************
*******************************************************************************************************
*******************************************************************************************************
*******************************************************************************************************
**----------------------------------------
**
** Print file details
**
**----------------------------------------
PrintFileDetails
move.l #NULL,d0 ; Clear new signal Test for CTRL_C
move.l d0,d1 ; Clear signal mask
move.l AbsExecBase,a6 ; Get exec.library base
jsr _LVOSetSignal(a6) ; Get signals
move.l DosBase(a5),a6 ; Get dos.library base
and.l #SIGBREAKF_CTRL_C,d0 ; Test for CTRL_C
beq FilNoEscape ; Jump if pressed
rts
FilNoEscape
; Print module name Print module name
lea ModuleNameMSG,a0 ; Get address of message
move.l ModuleNameMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
move.w ResNameTabOffset(a4),d0 ; Get offset to res nam table Get address of res nam table
rol.w #8,d0 ; Position bytes correctly
lea (a4,d0.w),a0 ; Get address of entry table
clr.l d3 ; Clear length of module name Print first entry
move.b (a0)+,d3 ; Get length of message
bsr PrintMSG ; Print module name
; Print module description Print module description
lea ModuleDescribeMSG,a0 ; Get address of message
move.l ModuleDescribeMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
move.l NonResNamTabOffset(a4),d0 ; Get offset to non res nam table Get address of non res nam table
rol.w #8,d0 ; Position bytes correctly
swap d0 ; Get low word
rol.w #8,d0 ; Position bytes correctly
sub.l HeaderOffset(a5),d0 ; Get offset to non-res table
lea (a4,d0.w),a0 ; Get address of entry table
clr.l d3 ; Clear length of module name Print first entry
move.b (a0)+,d3 ; Get length of message
bsr PrintMSG ; Print module name
; Print linker version number
lea VersionNumMSG,a0 ; Get address of message
move.l VersionNumMSGLen,d3 ; Get message length
bsr PrintMSG ; Print message
move.b LinkerVersionNum(a4),d3 ; Get linker version number
bsr ConvertBin2ASCII ; Convert to ASCII digits
move.b #"$",TempBuffer(a5) ; Put $ for hexadecimal numbe r
move.b d0,TempBuffer+1(a5) ; Store Hi digit for printing
move.b d1,TempBuffer+2(a5) ; Store Lo digit for printing
move.b #NewLine,TempBuffer+3(a5) ; New line
move.l #4,d3 ; 4 characters to be printed
lea TempBuffer(a5),a0 ; Get address of string
bsr PrintMSG ; Print the MSG
; Print linker revision number
lea RevisionNumMSG,a0 ; Get address of message
move.l RevisionNumMSGLen,d3 ; Get message length
bsr PrintMSG ; Print message
move.b LinkerRevisionNum(a4),d3; Get linker revision number
bsr ConvertBin2ASCII ; Convert to ASCII digits
move.b #"$",TempBuffer(a5) ; Put $ for hexadecimal number
move.b d0,TempBuffer+1(a5) ; Store Hi digit for printing
move.b d1,TempBuffer+2(a5) ; Store Lo digit for printing
move.b #NewLine,TempBuffer+3(a5) ; New line
move.l #4,d3 ; 4 characters to be printed
lea TempBuffer(a5),a0 ; Get address of string
bsr PrintMSG ; Print the MSG
; Print $0C flags data
lea ExecutableTypeMSG,a0 ; Get address of message
move.l ExecutableTypeMSGLen,d3 ; Get message length
bsr PrintMSG ; Print message
lea NormalExecutableMSG,a0 ; Get address of normal executable message
move.l NormalExecutableMSGLen,d3 ; Get length of message
btst #7,FileFlags+1(a4) ; Test bit 15 of file flags
beq NormalExecutable ; If bit is zero then normal executable
lea LibraryModuleMSG,a0 ; File is a library module
move.l LibraryModuleMSGLen,d3 ; Get length of above message
NormalExecutable
bsr PrintMSG ; Print file type message
lea FileDataModelMSG,a0 ; Get address of message
move.l FileDataModelMSGLen,d3 ; Get message length
bsr PrintMSG ; Print message
lea SingleDataModelMSG,a0 ; Get address of message
move.l SingleDataModelMSGLen,d3 ; Get message length
btst #0,FileFlags(a4) ; Test bit 0 of $0C
bne PrintDataModel ; If set then file is SINGLEDATA
lea MultipleDataModelMSG,a0 ; Get address of message
move.l MultipleDataModelMSGLen,d3 ; Get message length
btst #1,FileFlags(a4) ; Test bit 1 of $0C
bne PrintDataModel ; If set then file is MULTIPLEDATA
lea NoAutoDataModelMSG,a0 ; Get address of message
move.l NoAutoDataModelMSGLen,d3 ; Get message length
PrintDataModel
bsr PrintMSG ; Print message
lea IsSelfLoadingMSG,a0 ; Get address of message
move.l IsSelfLoadingMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
lea NoMSG,a0 ; Get address of message
move.l NoMSGLen,d3 ; Get length of message
btst #3,FileFlags+1(a4) ; Test if self loading EXE
beq NotSelfLoading ; Jump if not self loading EXE
lea YesMSG,a0 ; Else executable is self loading
move.l YesMSGLen,d3 ; Get length of message
NotSelfLoading
bsr PrintMSG ; Print the message
; Print auto data segment number. If file is NOAUTODATA then print that
lea AutoDataSegMSG,a0 ; Get address of message
move.l AutoDataSegMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
lea NoAutoDataModelMSG,a0 ; Get address of message
move.l NoAutoDataModelMSGLen,d3; Get message length
btst #3,FileFlags+1(a4) ; Test if self loading EXE
bne PrintAutoSegNum ; If it is then print the message
lea AutoDataSegNum(a4),a3 ; Get pointer to number
bsr PrePrintSingleIntelWord ; Prepare the number
PrintAutoSegNum
bsr PrintMSG ; Print the message
; Print initial local heap size, if 0 then print no local allocation
lea InitLocalHeapMSG,a0 ; Get address of message
move.l InitLocalHeapMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
lea InitLocalHeap(a4),a3 ; Get address of number
lea NoLocalHeapMSG,a0 ; Get no Alloc message address
move.l NoLocalHeapMSGLen,d3 ; Get message length
tst.w (a3) ; Is there a heap?
beq NoLocalHeap ; If no local heap then print message
bsr PrePrintSingleIntelWord ; Prepare heap size for printing
NoLocalHeap
bsr PrintMSG
; Print initial stack size
lea InitStackSizeMSG,a0 ; Get address of message
move.l InitStackSizeMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
lea InitStackSize(a4),a3 ; Get address of number
bsr PrePrintSingleIntelWord ; Prepare the stack size for printing
bsr PrintMSG ; Print the stack size
; Print CS:IP
lea InitCSIPMSG,a0 ; Get address of message
move.l InitCSIPMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
lea InitCSIP(a4),a3 ; Get address of number
bsr PrintSegOffset ; Print CS:IP
; Print SS:SP if SP=0 and SS=DS then SP= stacksize + data segment size
lea StackAddressMSG,a0 ; Get address of message
move.l StackAddressMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
lea InitSSSP(a4),a3 ; Get address of SS:SP
; Note the output below and that of MAPWIN etc. does not agree so I have decided to
; remove it for the moment. See docs!
; tst.w (a3) ; Is SP=0?
; bne NormalStack ; If not then print normally
; clr.l d0 ; Clear d0 for later use
; move.w InitSSSP+2(a4),d0 ; Get SS
; cmp.w AutoDataSegNum(a4),d0 ; Is SS=DS?
; bne NormalStack ; If not then print normally
;
; lea StackEquation(a5),a3 ; Temporary equation holder
; clr.l d1 ; Clear d1 for later use
; move.b InitSSSP+3(a4),d1 ; Get high byte of SS
; move.b d1,$03(a3) ; Save SS high for later printing
; lsl.w #8,d1 ; Position high byte correctly
; move.b InitSSSP+2(a4),d1 ; Get low byte of SS
; move.b d1,$02(a3) ; Save SS low for later printing
; subq.w #1,d1 ; Decrement it
; lsl.l #3,d1 ; Multiply by segment table entry size (8 bytes)
; move.b SegTableOffset+1(a4),d0 ; Get high byte of seg table offset
; lsl.w #8,d0 ; Position high byte correctly
; move.b SegTableOffset(a4),d0 ; Get low byte of seg table offset
; add.l d0,d1 ; Add offset to start of segment table
; move.b SegAllocSize+1(a4,d1),d0; Get high byte of segment allocation size
; lsl.w #8,d0 ; Position high byte correctly
; move.b SegAllocSize(a4,d1),d0 ; Get low byte of segment allocation size
; move.b InitStackSize+1(a4),d1 ; Get high byte of stack size
; lsl.w #8,d1 ; Position high byte correctly
; move.b InitStackSize(a4),d1 ; Get low byte of stack size
; add.w d0,d1 ; d1=SP
; move.b d1,$00(a3) ; Save low byte of SP
; lsr.w #8,d1 ; Get high byte of SP
; move.b d1,$01(a3) ; Save high byte of SP
;
NormalStack
bsr PrintSegOffset ; Print SS:SP
rts ; Finish printing file data
**--------------------------------------------
**
** Print segment table
**
**--------------------------------------------
; Print offset to start of segment table
PrintSegmentTable
move.l #NULL,d0 ; Clear new signal Test for CTRL_C
move.l d0,d1 ; Clear signal mask
move.l AbsExecBase,a6 ; Get exec.library base
jsr _LVOSetSignal(a6) ; Get signals
move.l DosBase(a5),a6 ; Get dos.library base
and.l #SIGBREAKF_CTRL_C,d0 ; Test for CTRL_C
beq SegNoEscapeStart ; Jump if pressed
rts
SegNoEscapeStart
lea SegTableOffsetMSG,a0 ; Get address of message Print offset to start of segment table
move.l SegTableOffsetMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print message
lea SegTableOffset(a4),a3 ; Get address of offset
bsr PrePrintSingleIntelWord ; Prepare number for printing
bsr PrintMSG ; Print the number
; Print number of entries in segment table
lea SegTableEntryNumMSG,a0 ; Get address of message Print number of entries in segment table
move.l SegTableEntryNumMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print message
lea SegTableEntryNum(a4),a3 ; Get address of number of entries
bsr PrePrintSingleIntelWord ; Prepare number for printing
bsr PrintMSG ; Print the number
; Print contents of segment table
clr.l d0 ; Clear d0
move.w SegTableOffset(a4),d6 ; Get offset to table d6=offset to seg table this is for later
rol.w #8,d6 ; Position high byte correctly
bsr PrePrintSingleIntelWord ; Prepare number for printing
move.w SegTableEntryNum(a4),d7 ; Get number of entries d7=n this is for the FOR later
rol.w #8,d7 ; Position high byte correctly
; subq.w #1,d7 ; Segment number starts with 1
move.w #1,d5 ; Counter for segment number
PrintSegmentTableEntry ; REPEAT
move.l #NULL,d0 ; Clear new signal Test for CTRL_C
move.l d0,d1 ; Clear signal mask
move.l AbsExecBase,a6 ; Get exec.library base
jsr _LVOSetSignal(a6) ; Get signals
move.l DosBase(a5),a6 ; Get dos.library base
and.l #SIGBREAKF_CTRL_C,d0 ; Test for CTRL_C
beq SegNoEscape ; Jump if pressed
rts
SegNoEscape
lea SegmentNumberMSG,a0 ; Get address of message Print segment number
move.l SegmentNumberMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
move.w d5,d0 ; d0=segment number for printing
move.b d0,StackEquation(a4) ; Put low byte of seg num for printing
lsr.w #8,d0 ; Get high byte
move.b d0,StackEquation+1(a4) ; Put high byte of seg num for printing
lea StackEquation(a4),a3 ; Get address of number for printing
bsr PrePrintSingleIntelWord ; Prepare number for printing
bsr PrintMSG ; Print the number
lea NoDataInSegmentMSG,a0 ; Get address of message Check offset 0 of each entry and
move.l NoDataInSegmentMSGLen,d3; Get length of message
tst.w DataOffset(a4,d6) ; Is there any data?
beq NoDataInSegment ; Print message if 0 If 0 then print "No data provided for this segment"
lea FileSegLengthMSG,a0 ; Get address of message else print size of segment in file
move.l FileSegLengthMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
lea SixtyFourKMSG,a0 ; Get address of message
move.l SixtyFourKMSGLen,d3 ; Get length of message
lea FileSegLength(a4,d6),a3 ; Get address of number
tst.w (a3) ; Is it zero? Which means 64k allocated
beq NoDataInSegment ; If 64k size then print that
bsr PrePrintSingleIntelWord ; Prepare file segment length for printing
NoDataInSegment
bsr PrintMSG ; Print message
MinAllocForSegment
lea MinAllocForSegMSG,a0 ; Get address of message Print minimum allocation for this segment
move.l MinAllocForSegMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
lea SixtyFourKMSG,a0 ; Get address of message
move.l SixtyFourKMSGLen,d3 ; Get length of message
lea SegAllocSize(a4,d6),a3 ; Get address of number
tst.w (a3) ; Is it zero? Which means 64k allocated
beq AllocWholeSegment ; If 64k size then print that
bsr PrePrintSingleIntelWord ; Prepare file segment length for printing
AllocWholeSegment
bsr PrintMSG ; Print message
lea SegmentTypeMSG,a0 ; Get address of message Print "Segment type"
move.l SegmentTypeMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
lea DataMSG,a0 ; Get address of message If bit 0 of flag set then segment is type data
move.l DataMSGLen,d3 ; Get length of message
btst #0,SegFlags(a4,d6) ; Test bit 0 of segment flags
bne PrintSegmentType ; If set then print type data
lea CodeMSG,a0 ; Get address of message else print type code
move.l CodeMSGLen,d3 ; Get length of message
PrintSegmentType
bsr PrintMSG ; Print the message
btst #1,SegFlags(a4,d6) ; Test bit 1 of seg flags If bit 1 set then print "Loader allocates mem..."
beq NoLoaderAllocation ; If zero then no allocation
lea LoaderAllocMSG,a0 ; Get address of message
move.l LoaderAllocMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
NoLoaderAllocation
btst #2,SegFlags(a4,d6) ; Test bit 2 of seg flags If bit 2 set then print "Segment is loaded..."
beq SegmentNotLoaded ; If zero then segment not loaded
lea SegmentLoadedMSG,a0 ; Get address of message
move.l SegmentLoadedMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
SegmentNotLoaded
lea MoveableMSG,a0 ; Get address of message If bit 4 of flag set then segment is moveable
move.l MoveableMSGLen,d3 ; Get length of message
btst #4,SegFlags(a4,d6) ; Test bit 4 of segment flags
bne PrintSegmentReloc ; If set then print type moveable
lea FixedMSG,a0 ; Get address of message else print type fixed
move.l FixedMSGLen,d3 ; Get length of message
PrintSegmentReloc
bsr PrintMSG ; Print the message
lea ShareMSG,a0 ; Get address of message If bit 5 of flag set then segment is pure or sharable
move.l ShareMSGLen,d3 ; Get length of message
btst #5,SegFlags(a4,d6) ; Test bit 5 of segment flags
bne PrintSegmentSharing ; If set then print type shareable
lea NonShareMSG,a0 ; Get address of message else print type non shareable
move.l NonShareMSGLen,d3 ; Get length of message
PrintSegmentSharing
bsr PrintMSG ; Print the message
lea PreLoadMSG,a0 ; Get address of message If bit 6 of flag set then preload segment
move.l PreLoadMSGLen,d3 ; Get length of message
btst #6,SegFlags(a4,d6) ; Test bit 6 of segment flags
bne PrintSegmentLoadType ; If set then print type preload
lea LoadOnCallMSG,a0 ; Get address of message else print type load on call
move.l LoadOnCallMSGLen,d3 ; Get length of message
PrintSegmentLoadType
bsr PrintMSG ; Print the message
btst #7,SegFlags(a4,d6) ; Test bit 7 of segment flags If bit 7 set then
beq RandomAccess ; Random access
lea ReadOnlyMSG,a0 ; Get address of message
move.l ReadOnlyMSGLen,d3 ; Get length of message
btst #0,SegFlags(a4,d6) ; Test bit 0 of segment flags If bit 0 set then print "READONLY"
bne ReadOnlySegment ; Print "READONLY" if data seg
lea ExecuteOnlyMSG,a0 ; Get address of message else print "EXECUTEONLY"
move.l ExecuteOnlyMSGLen,d3 ; Get length of message
ReadOnlySegment
bsr PrintMSG ; Print the message
RandomAccess ; Come here for no access restrictions
btst #0,SegFlags+1(a4,d6) ; Test bit 8 of segment flags If bit 8 set then print "Segment contains relocation data"
beq NoRelocation ; Jump if bit not set
lea SegRelocationMSG,a0 ; Get address of message
move.l SegRelocationMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
NoRelocation
btst #0,SegFlags+1(a4,d6) ; Test bit 8 of segment flags If bit 8 set then print "Segment contains relocation data"
beq NoDiscard ; Jump if bit not set
lea SegDiscardMSG,a0 ; Get address of message
move.l SegDiscardMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
NoDiscard
addq.l #8,d6 ; Bump to next entry
addq.w #1,d5 ; Increment the segment counter
subq.w #1,d7 ; Decrement the loop counter
bne PrintSegmentTableEntry ; Loop if not zero
rts ; Finish printing segment table
**---------------------------------------
**
** Print resource table
**
**---------------------------------------
PrintResourceTable
move.l #NULL,d0 ; Clear new signal Test for CTRL_C
move.l d0,d1 ; Clear signal mask
move.l AbsExecBase,a6 ; Get exec.library base
jsr _LVOSetSignal(a6) ; Get signals
move.l DosBase(a5),a6 ; Get dos.library base
and.l #SIGBREAKF_CTRL_C,d0 ; Test for CTRL_C
beq ResNoEscape ; Jump if pressed
rts
ResNoEscape
lea RscTableOffsetMSG,a0 ; Get address of message ; Print offset to resource table
move.l RscTableOffsetMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
lea RscTableOffset(a4),a3 ; Get pointer to offset
move.w (a3),d7 ; Save offset of resource table
rol.w #8,d7 ; Swap bytes for intel word
bsr PrePrintSingleIntelWord ; Prepare number for printing
bsr PrintMSG ; Print the number
; Print contents of resource table
lea rscAlignShiftMSG,a0 ; Get address of message ; Print rscAlignShift
move.l rscAlignShiftMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
lea rscAlignShift(a4,d7.w),a3 ; Get pointer to shift count
move.w (a3),d4 ; Get shift count
rol.w #8,d4 ; Position bytes correctly
cmp.w #31,d4 ; Check validity
bgt NoResourceTable ; Jump if out of bounds
bsr PrePrintSingleIntelWord ; Prepare number for printing
bsr PrintMSG ; Print the number
move.w d7,d6 ; Get pointer to table
addq.w #2,d6 ; Increment pointer in
; Print rscTypes
PrintrscTypes ; REPEAT
move.l #NULL,d0 ; Clear new signal Test for CTRL_C
move.l d0,d1 ; Clear signal mask
move.l AbsExecBase,a6 ; Get exec.library base
jsr _LVOSetSignal(a6) ; Get signals
move.l DosBase(a5),a6 ; Get dos.library base
and.l #SIGBREAKF_CTRL_C,d0 ; Test for CTRL_C
beq RscNoEscape ; Jump if not pressed
rts
RscNoEscape
lea ResourceTypeMSG,a0 ; Get address of message Print "Resource type : "
move.l ResourceTypeMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
clr.l d0 ; Put d0 to zero
move.w (a4,d6.w),d0 ; Get rtTypeID
rol.w #8,d0 ; Position bytes correctly
move.l d0,a0 ; Get offset of string If rtTypeID < $8000 then
add.w d7,a0 ; Add offset of resource table
clr.l d3 ; Clear d3
add.l a4,a0 ; Add base of header
move.b (a0)+,d3 ; Get length of name
cmp.w #$8000,d0 ; Compare with $8000 n=(rtTypeID+resource table base)
blt PrintTherscType ; Print if less than Print n chars from above address+1
lea RT_CursorMSG,a0 ; Get address of message If rtTypeID = $8000 + 1 then print "RT_CURSOR"
move.l RT_CursorMSGLen,d3 ; Get length of message
cmp.w #$8000+1,d0 ; Compare with $8000+1
beq PrintTherscType ; Print if equal
lea RT_BitmapMSG,a0 ; Get address of message If rtTypeID = $8000 + 2 then print "RT_BITMAP"
move.l RT_BitmapMSGLen,d3 ; Get length of message
cmp.w #$8000+2,d0 ; Compare with $8000+2
beq PrintTherscType ; Print if equal
lea RT_IconMSG,a0 ; Get address of message If rtTypeID = $8000 + 3 then print "RT_ICON"
move.l RT_IconMSGLen,d3 ; Get length of message
cmp.w #$8000+3,d0 ; Compare with $8000+3
beq PrintTherscType ; Print if equal
lea RT_MenuMSG,a0 ; Get address of message If rtTypeID = $8000 + 4 then print "RT_MENU"
move.l RT_MenuMSGLen,d3 ; Get length of message
cmp.w #$8000+4,d0 ; Compare with $8000+4
beq PrintTherscType ; Print if equal
lea RT_DialogMSG,a0 ; Get address of message If rtTypeID = $8000 + 5 then print "RT_DIALOG"
move.l RT_DialogMSGLen,d3 ; Get length of message
cmp.w #$8000+5,d0 ; Compare with $8000+5
beq PrintTherscType ; Print if equal
lea RT_StringMSG,a0 ; Get address of message If rtTypeID = $8000 + 6 then print "RT_STRING"
move.l RT_StringMSGLen,d3 ; Get length of message
cmp.w #$8000+6,d0 ; Compare with $8000+6
beq PrintTherscType ; Print if equal
lea RT_FontDirMSG,a0 ; Get address of message If rtTypeID = $8000 + 7 then print "RT_FONTDIR"
move.l RT_FontDirMSGLen,d3 ; Get length of message
cmp.w #$8000+7,d0 ; Compare with $8000+7
beq PrintTherscType ; Print if equal
lea RT_FontMSG,a0 ; Get address of message If rtTypeID = $8000 + 8 then print "RT_FONT"
move.l RT_FontMSGLen,d3 ; Get length of message
cmp.w #$8000+8,d0 ; Compare with $8000+8
beq PrintTherscType ; Print if equal
lea RT_AcceleratorMSG,a0 ; Get address of message If rtTypeID = $8000 + 9 then print "RT_ACCELERATOR"
move.l RT_AcceleratorMSGLen,d3 ; Get length of message
cmp.w #$8000+9,d0 ; Compare with $8000+9
beq PrintTherscType ; Print if equal
lea RT_RCDataMSG,a0 ; Get address of message If rtTypeID = $8000 + 10 then print "RT_RCDATA"
move.l RT_RCDataMSGLen,d3 ; Get length of message
cmp.w #$8000+10,d0 ; Compare with $8000+10
beq PrintTherscType ; Print if equal
lea RT_Group_CursorMSG,a0 ; Get address of message If rtTypeID = $8000 + 12 then print "RT_GROUP_CURSOR"
move.l RT_Group_CursorMSGLen,d3; Get length of message
cmp.w #$8000+12,d0 ; Compare with $8000+12
beq PrintTherscType ; Print if equal
lea RT_Group_IconMSG,a0 ; Get address of message If rtTypeID = $8000 + 14 then print "RT_GROUP_ICON"
move.l RT_Group_IconMSGLen,d3 ; Get length of message
cmp.w #$8000+14,d0 ; Compare with $8000+14
beq PrintTherscType ; Print if equal
lea RT_VersionInfoMSG,a0 ; Get address of message If rtTypeID = $8000 + 16 then print "Version info?"
move.l RT_VersionInfoMSGLen,d3 ; Get length of message
cmp.w #$8000+16,d0 ; Compare with $8000+16
beq PrintTherscType ; Print if equal
lea RT_UnkRscTypeMSG,a0 ; Get address of message ELSE Print "Unknown resource type",rtTypeID
move.l RT_UnkRscTypeMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
lea (a4,d6.w),a3 ; Get address of number
bsr PrePrintSingleIntelWord ; Prepare number for printing
PrintTherscType
bsr PrintMSG ; Print the message
addq.w #2,d6 ; Increment pointer
lea rtResourceCountMSG,a0 ; Get address of message Print rtResourceCount
move.l rtResourceCountMSGLen,d3; Get length of message
bsr PrintMSG ; Print the message
lea (a4,d6.w),a3 ; Get address of rtResourceCount
move.w (a3),d5
bsr PrePrintSingleIntelWord ; Prepare word for printing
bsr PrintMSG ; Print the number
addq.w #6,d6 ; Increment pointer Skip rtReserved (longword)
; move.w (a3),d5 ; d5 = rtResourceCount FOR n-1 to rtResourceCount
rol.w #8,d5 ; Position the bytes right
PrintrtNameInfo ; Print rtNameInfo
lea rnOffsetMSG,a0 ; Get address of message Print rnOffset
move.l rnOffsetMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
clr.l d0 ; Clear d0
move.w rnOffset(a4,d6.w),d0 ; Get rnOffset
rol.w #8,d0 ; Position the bytes correctly
lsl.l d4,d0 ; Shift to size
bsr PrintMotoRegNum ; Print the number
lea rnLengthMSG,a0 ; Get address of message ; Print rnLength
move.l rnLengthMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
clr.l d0 ; Clear d0
move.w rnLength(a4,d6.w),d0 ; Get rnOffset
rol.w #8,d0 ; Position the bytes correctly
lsl.l d4,d0 ; Shift to size
bsr PrintMotoRegNum ; Print the number
; Print rnFlags Print rnFlags
lea rnFlagsMSG,a0 ; Get address of message Print "Resource flags"
move.l rnFlagsMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
btst #4,rnFlags(a4,d6.w) ; Test bit 4 of rnFlags If bit 4 set then print "MOVEABLE"
beq rnFlagsNotMoveable ; Jump if flag not set
lea rnFlagsMoveableMSG,a0 ; Get address of message
move.l rnFlagsMoveableMSGLen,d3; Get length of message
bsr PrintMSG ; Print the message
rnFlagsNotMoveable
btst #5,rnFlags(a4,d6.w) ; Test bit 6 of rnFlags If bit 5 set then print "PURE"
beq rnFlagsNotPure ; Jump if flag not set
lea rnFlagsPureMSG,a0 ; Get address of message
move.l rnFlagsPureMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
rnFlagsNotPure
btst #6,rnFlags(a4,d6.w) ; Test bit 6 of rnFlags If bit 6 set then print "PRELOAD"
beq PrintrnID ; Jump if flag not set
lea rnFlagsPreloadMSG,a0 ; Get address of message
move.l rnFlagsPreloadMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
PrintrnID ; Print rnID
lea rnIDMSG,a0 ; Get address of message Print "Resource ID is"
move.l rnIDMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
move.w rnID(a4,d6.w),d0 ; Get rnID If rnID >= $8000 then print rnID-$8000
bclr #7,d0 ; Clear MSBit of intel word
lea StackEquation(a5),a3 ; Get temporary address
move.w d0,(a3) ; Store ID
bsr PrePrintSingleIntelWord ; Prepare the word for printing
btst #7,rnID+1(a4,d6.w) ; Test bit 15 of rnID
bne EndFORrnNameInfo ; Jump if set
lea rnID(a4,d6.w),a0 ; Get rnID address ELSE
clr.l d0 ; Clear scratch register x=(rnID+resource table base)
move.l d0,d3 ; Clear d3 also Print x chars from above table
move.w (a0),d0 ; Get offset
rol.w #8,d0 ; Position bytes correctly
move.l d0,a0 ; Get address of string
add.w d7,a0 ; Add base of resource table
add.l a4,a0 ; Add base of header
move.b (a0)+,d3 ; Get length of string
EndFORrnNameInfo
bsr PrintMSG ; Print the message
add.w #12,d6 ; Skip to next entry Skip to next entry
subq.w #1,d5 ; Decrement n FOR loop
bne PrintrtNameInfo ; Loop if not zero ; END ; FOR
tst.w (a4,d6.w) ; Test next byte
bne PrintrscTypes ; Loop if not zero ; UNTIL rscEndTypes ; ie. next byte = 0
NoResourceTable
rts ; End of printing
**------------------------------------------
**
** Print resident-name table
**
**------------------------------------------
PrintResNameTable
move.l #NULL,d0 ; Clear new signal Test for CTRL_C
move.l d0,d1 ; Clear signal mask
move.l AbsExecBase,a6 ; Get exec.library base
jsr _LVOSetSignal(a6) ; Get signals
move.l DosBase(a5),a6 ; Get dos.library base
and.l #SIGBREAKF_CTRL_C,d0 ; Test for CTRL_C
beq ResNamNoEscape ; Jump if pressed
rts
ResNamNoEscape
lea ResNamTableMSG,a0 ; Get address of message Print resident-name table
move.l ResNamTableMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
clr.l d7 ; Clear d7 Get address of resident-name table
move.w ResNameTabOffset(a4),d7 ; Get offset
rol.w #8,d7 ; Position bytes correctly
add.l a4,d7 ; Get address of table
move.l d7,a0 ; Put in address register Skip first entry
move.b (a0)+,d3 ; Get length of module Get length of string
add.l d3,a0 ; Skip past name Add to pointer
addq.l #2,a0 ; Skip ordinal Add 2 to pointer to skip ordinal
PrintResNamTabString
tst.b (a0) ; Test next byte WHILE next byte !=0
beq ResNamTabFinished ; Jump if 0
move.l a0,d7 ; Save pointer
lea SixBlankSpacesMSG,a0 ; Get address of message
move.l SixBlankSpacesMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
move.l d7,a0 ; Get pointer Get length of string
move.b (a0)+,d3 ; Get length of string
move.l a0,d7 ; Save pointer
add.l d3,d7 ; Add string length Skip pointer past string
bsr PrintMSG ; Print the string Print string
lea SixBlankSpacesMSG,a0 ; Get address of message
move.l SixBlankSpacesMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
move.l d7,a3 ; Put pointer in a3 Print ordinal
bsr PrePrintSingleIntelWord ; Prepare the number
bsr PrintMSG ; Print the number
addq.l #2,d7 ; Skip past ordinal
move.l d7,a0 ; Get pointer
bra PrintResNamTabString ; Loop END ; WHILE
ResNamTabFinished
rts ; Return
**--------------------------------------------------
**
** Print module-reference and imported-name tables
**
**--------------------------------------------------
PrintModImpTables
move.l #NULL,d0 ; Clear new signal Test for CTRL_C
move.l d0,d1 ; Clear signal mask
move.l AbsExecBase,a6 ; Get exec.library base
jsr _LVOSetSignal(a6) ; Get signals
move.l DosBase(a5),a6 ; Get dos.library base
and.l #SIGBREAKF_CTRL_C,d0 ; Test for CTRL_C
beq ModImpNoEscape ; Jump if pressed
rts
ModImpNoEscape
lea ModTableEntriesMSG,a0 ; Get address of message Print module-reference and imported-name tables
move.l ModTableEntriesMSGLen,d3; Get length of message Print number of entries in module-reference table
bsr PrintMSG ; Print the message
lea ModTableEntries(a4),a3 ; Point to entries in mod tab
move.w (a3),d7 ; Get number of entries
rol.w #8,d7 ; Position bytes correctly
bsr PrePrintSingleIntelWord ; Prepare for printing
bsr PrintMSG ; Print the number
clr.l d6 ; Clear d6 Get address of imported-name table
move.w ImpTableOffset(a4),d6 ; Get offset to imp tab
rol.w #8,d6 ; Position the bytes correctly
add.l a4,d6 ; Add base of header
addq.w #1,d7 ; Add extra 1
PrintModRefStrings ; FOR n=1 to number of entries in module-reference table
lea SixBlankSpacesMSG,a0 ; Get address of message
move.l SixBlankSpacesMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
move.l d6,a0 ; Get pointer Get length of string
move.b (a0)+,d3 ; Get length of string
move.l a0,d6 ; Save pointer Get address of string
add.l d3,d6 ; Skip past string
bsr PrintMSG ; Print string Print string
lea NewLineMSG,a0 ; Get address of message
move.l NewLineMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
subq.w #1,d7 ; Decrement counter END ; FOR
bne PrintModRefStrings ; Loop
rts ; Finished
**------------------------------------------
**
** Print non-resident name table
**
**------------------------------------------
PrintNonResNameTable
move.l #NULL,d0 ; Clear new signal Test for CTRL_C
move.l d0,d1 ; Clear signal mask
move.l AbsExecBase,a6 ; Get exec.library base
jsr _LVOSetSignal(a6) ; Get signals
move.l DosBase(a5),a6 ; Get dos.library base
and.l #SIGBREAKF_CTRL_C,d0 ; Test for CTRL_C
beq NonResNoEscape ; Jump if pressed
rts
NonResNoEscape
lea NonResNamTableMSG,a0 ; Get address of message Print resident-name table
move.l NonResNamTableMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
clr.l d7 ; Clear d7 Get address of resident-name table
move.l NonResNamTabOffset(a4),d7 ; Get offset
rol.w #8,d7 ; Position bytes correctly
swap d7 ; swap register halves
rol.w #8,d7 ; Position bytes correctly
sub.l HeaderOffset(a5),d7 ; Get address of table
add.l a4,d7 ; Add offset to table
move.l d7,a0 ; Put in address register Skip first entry
move.b (a0)+,d3 ; Get length of module Get length of string
add.l d3,a0 ; Skip past name Add to pointer
addq.l #2,a0 ; Skip ordinal Add 2 to pointer to skip ordinal
PrintNonResNamTabString
tst.b (a0) ; Test next byte WHILE next byte !=0
beq NonResNamTabFinished ; Jump if 0
move.l a0,d7 ; Save pointer
lea SixBlankSpacesMSG,a0 ; Get address of message
move.l SixBlankSpacesMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
move.l d7,a0 ; Get pointer Get length of string
move.b (a0)+,d3 ; Get length of string
move.l a0,d7 ; Save pointer
add.l d3,d7 ; Add string length Skip pointer past string
bsr PrintMSG ; Print the string Print string
lea SixBlankSpacesMSG,a0 ; Get address of message
move.l SixBlankSpacesMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
move.l d7,a3 ; Put pointer in a3 Print ordinal
bsr PrePrintSingleIntelWord ; Prepare the number
bsr PrintMSG ; Print the number
addq.l #2,d7 ; Skip past ordinal
move.l d7,a0 ; Get pointer
bra PrintNonResNamTabString ; Loop END ; WHILE
NonResNamTabFinished
rts ; Return
**---------------------------------------------
**
** Print entry table
**
**---------------------------------------------
PrintEntryTable ; Print entry table
move.l #NULL,d0 ; Clear new signal Test for CTRL_C
move.l d0,d1 ; Clear signal mask
move.l AbsExecBase,a6 ; Get exec.library base
jsr _LVOSetSignal(a6) ; Get signals
move.l DosBase(a5),a6 ; Get dos.library base
and.l #SIGBREAKF_CTRL_C,d0 ; Test for CTRL_C
beq EntNoEscape ; Jump if pressed
rts
EntNoEscape
lea EntryTableMSG,a0 ; Get address of message
move.l EntryTableMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
tst.w EntryLength(a4) ; Test number Test length of entry table
beq EntryTableFinished ; Quit if 0
clr.l d5 ; Clear d5
moveq.l #1,d6 ; Initialize entry counter If length != 0 then
move.w EntryOffset(a4),d7 ; Get offset Get address of entry table
rol.w #8,d7 ; Position bytes correctly
PrintEntryTableBundles ; REPEAT
move.l #NULL,d0 ; Clear new signal Test for CTRL_C
move.l d0,d1 ; Clear signal mask
move.l AbsExecBase,a6 ; Get exec base
jsr _LVOSetSignal(a6) ; Get signals
move.l DosBase(a5),a6 ; Get dos.library base
and.l #SIGBREAKF_CTRL_C,d0 ; Test for CTRL_C
beq EntryNoEscape ; Jump if pressed
rts
EntryNoEscape
move.b EntryBndlNum(a4,d7.w),d5; Get number of entries Get number of entries in bundle
move.b EntryBndlTyp(a4,d7.w),d4; Get entry type Get bundle type
addq.w #2,d7 ; Add 2 to pointer Add 2 to pointer
tst.b d4 ; Is d4 = 0 ? If bundle type = 0 then ; Null entries
beq EntryZeroBundle ; Branch if 0
cmp.b #$FE,d4 ; Is d4 = $FE If bundle type = $FE then ; Constant pointer
beq EntryConstBundle ; Jump if $FE
cmp.b #$FF,d4 ; Is d4 = $FF
beq EntryMoveBundle ; Jump if $FF If bundle type = $FF then ; Movable segment
; Print fixed segment records ELSE
lea EntryFixSegRecrMSG,a0 ; Get address of message Print "Fixed segment records : "
move.l EntryFixSegRecrMSGLen,d3; Get length of message
bsr PrintMSG ; Print the message
move.b d5,d3 ; Move byte for printing
bsr PrintByte ; Print a byte number ,entries in bundle,
lea EntryEntriesSegMSG,a0 ; Get address of message " entries. Segment : "
move.l EntryEntriesSegMSGLen,d3; Get length of message
bsr PrintMSG ; Print the message
move.b d4,d3 ; Move byte for printing ,bundle type
bsr PrintByte ; Print the number
EntryPrintFixSeg ; FOR n=1 to entries in bundle
bsr PrintEntryNumber ; Print entry Print "Entry ",entry counter
lea EntryFixOffsetMSG,a0 ; Get address of message Print "Offset : ",EntryFixOffset
move.l EntryFixOffsetMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
lea EntryFixOffset(a4,d7.w),a3 ; Get address of offset
bsr PrePrintSingleIntelWord ; Prepare num for printing
subq.l #1,d3 ; No new line
bsr PrintMSG ; Print number
btst #0,EntryFixFlags(a4,d7.w) ; Test flag If bit 0 of EntryFixFlags = 1 then
beq EntryFixNotExported ; Jump if 0
bsr PrintEntryExported ; Print exported Print Exported
EntryFixNotExported
btst #1,EntryFixFlags(a4,d7.w) ; Test flag If bit 1 of EntryFixFlags = 1 then
beq EntryFixNotGlobal ; Jump if 0
lea SingleDataModelMSG,a0 ; Get address of message Print "SINGLEDATA"
move.l SingleDataModelMSGLen,d3; Get length of message
bsr PrintMSG ; Print the message
EntryFixNotGlobal
addq.w #3,d7 ; Add 3 to pointer Add 3 to pointer
addq.l #1,d6 ; Increment entry number END ; FOR
subq.b #1,d5 ; Decrement number of entries in bundle
bne EntryPrintFixSeg ; Loop
bra EntryFinished ; Finished
; Print null entry bundles
EntryZeroBundle
lea EntryNullEntriesMSG,a0 ; Get address of message Print "Null entries : "
move.l EntryNullEntriesMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
move.b d5,d3 ; Get number of entries ,entries
bsr PrintByte ; Print the number
add.l d5,d6 ; Add entries to counter Add entries to entry counter
bra EntryFinished ; Null entries done
; Constant pointer
EntryConstBundle
lea EntryConstantMSG,a0 ; Get address of message Print "Constant records : "
move.l EntryConstantMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
move.b d5,d3 ; Move byte for printing
bsr PrintByte ; Print a byte number ,entries in bundle,
lea EntryEntriesMSG,a0 ; Get address of message " entries."
move.l EntryEntriesMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
EntryPrintConstSeg ; FOR n=1 to entries in bundle
bsr PrintEntryNumber ; Print entry Print "Entry ",entry counter
lea EntryFixOffsetMSG,a0 ; Get address of message Print "Offset : ",EntryConstValue
move.l EntryFixOffsetMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
lea EntryConstValue(a4,d7.w),a3 ; Get address of offset
bsr PrePrintSingleIntelWord ; Prepare num for printing
subq.l #1,d3 ; No new line
bsr PrintMSG ; Print number
btst #0,EntryConstFlags(a4,d7.w) ; Test flag If bit 0 of EntryFixFlags = 1 then
beq EntryConstNotExported ; Jump if 0
bsr PrintEntryExported ; Print exported Print Exported
EntryConstNotExported
btst #1,EntryConstFlags(a4,d7.w) ; Test flag If bit 1 of EntryFixFlags = 1 then
beq EntryConstNotGlobal ; Jump if 0
lea SingleDataModelMSG,a0 ; Get address of message Print "SINGLEDATA"
move.l SingleDataModelMSGLen,d3; Get length of message
bsr PrintMSG ; Print the message
EntryConstNotGlobal
addq.w #3,d7 ; Add 3 to pointer Add 3 to pointer
addq.l #1,d6 ; Increment entry number END ; FOR
subq.b #1,d5 ; Decrement number of entries in bundle
bne EntryPrintConstSeg ; Loop
bra EntryFinished ; Finished
; Print moveable segment record
EntryMoveBundle
lea EntryMoveRecrMSG,a0 ; Get address of message Print "Movable segment records : "
move.l EntryMoveRecrMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
move.b d5,d3 ; Move byte for printing
bsr PrintByte ; Print a byte number ,entries in bundle,
lea EntryEntriesMSG,a0 ; Get address of message Print "entries"
move.l EntryEntriesMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
EntryPrintMoveSeg ; FOR n=1 to entries in bundle
bsr PrintEntryNumber ; Print entry Print "Entry ",entry counter
lea EntryMoveSegMSG,a0 ; Get address of message Print "Segment : ",EntryMoveSeg
move.l EntryMoveSegMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
move.b EntryMoveSeg(a4,d7.w),d3; Get address of offset
bsr PrintByte ; Prepare num for printing
lea EntryMoveOffsetMSG,a0 ; Get address of message Print "Offset : ",EntryMoveOffset
move.l EntryMoveOffsetMSGLen,d3; Get length of message
bsr PrintMSG ; Print the message
lea EntryMoveOffset(a4,d7.w),a3 ; Get address of offset
bsr PrePrintSingleIntelWord ; Prepare num for printing
subq.l #1,d3 ; No new line
bsr PrintMSG ; Print number
btst #0,EntryMoveFlags(a4,d7.w) ; Test flag If bit 0 of EntryFixFlags = 1 then
beq EntryMoveNotExported ; Jump if 0
bsr PrintEntryExported ; Print exported Print Exported
EntryMoveNotExported
btst #1,EntryFixFlags(a4,d7.w) ; Test flag If bit 1 of EntryFixFlags = 1 then
beq EntryMoveNotGlobal ; Jump if 0
lea GlobalMSG,a0 ; Get address of message Print "GLOBAL"
move.l GlobalMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
EntryMoveNotGlobal
addq.w #6,d7 ; Add 6 to pointer Add 6 to pointer
addq.l #1,d6 ; Increment entry number END ; FOR
subq.b #1,d5 ; Decrement number of entries in bundle
bne EntryPrintMoveSeg ; LoopEntryFinished
EntryFinished
tst.b (a4,d7.w) ; Is next byte = 0 UNTIL next byte = 0
bne PrintEntryTableBundles ; Loop
EntryTableFinished
rts ; Finished
PrintEntryNumber
lea EntryNumberMSG,a0 ; Get address of message Print "Entry : "
move.l EntryNumberMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
move.l d6,d0 ; Get entry counter ,entry counter
rol.w #8,d0 ; Convert to intel form
swap d0 ; Swap register halves
rol.w #8,d0 ; Convert to intel form
move.l d0,StackEquation(a5) ; Put number for printing
lea StackEquation(a5),a3 ; Get address of number
lea TempBuffer(a5),a1 ; Get address of printing buffer
move.l a1,a0 ; Make a copy of buffer address
move.b #"$",(a1)+ ; Put $ for hexadecimal
addq.l #2,a3 ; Bump pointer to segment number
bsr PrePrintIntelWord ; Print the segment number
move.b #":",(a1)+ ; Character in between seg and offset
subq.l #4,a3 ; Bump pointer back to offset
bsr PrePrintIntelWord ; Print the offset number
move.l #10,d3 ; Length of string
bra PrintMSG ; Print string
PrintEntryExported
lea EntryExportedMSG,a0 ; Get address of message Print "Exported"
move.l EntryExportedMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
rts ; Return
**----------------------------------------------
**
** Print relocation tables
**
**----------------------------------------------
PrintRelocTabs ; Print segment relocations
move.l #NULL,d0 ; Clear new signal Test for CTRL_C
move.l d0,d1 ; Clear signal mask
move.l AbsExecBase,a6 ; Get exec.library base
jsr _LVOSetSignal(a6) ; Get signals
move.l DosBase(a5),a6 ; Get dos.library base
and.l #SIGBREAKF_CTRL_C,d0 ; Test for CTRL_C
bne UserBreakHere ; Jump if pressed
lea PrintRelocationMSG,a0 ; Get address of message Print "Segment relocations"
move.l PrintRelocationMSGLen,d3; Get length of message
bsr PrintMSG ; Print the message
move.l #1,d7 ; d7=segment counter Initialize segment counter
move.w SegTableOffset(a4),d5 ; Get seg table offset Get address of segment table
rol.w #8,d5 ; d5=Pointer in seg table
move.w SegTableEntryNum(a4),d6 ; Get seg table entries Get number of entries in segment table
rol.w #8,d6 ; d6=Seg table entries (n)
SearchSegTab4Reloc ; FOR n=1 to entries in segment table
btst #0,SegFlags+1(a4,d5.w) ; Test bit 8 of segment flags If this segment contains relocation data
beq NoRelocInThisSeg ; Jump if no relocations
lea RelocForSegMSG,a0 ; Get address of message Print "Relocations for segment "
move.l RelocForSegMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
move.w d7,d0 ; Get temp copy of seg num ,segment counter
rol.w #8,d0 ; Make intel word
lea StackEquation(a5),a3 ; Get temporary address
move.w d0,(a3) ; Save number
bsr PrePrintSingleIntelWord ; Prepare for printing
bsr PrintMSG ; Print the number
clr.l d2 ; Clear d2 for later
move.l d2,d0 ; Clear d0 for later too
move.b ShiftCount(a4),d0 ; Get shift count Goto position of segment in file
move.w SegmentPos(a4,d5.w),d2 ; Get position of segment
rol.w #8,d2 ; Position bytes correctly
lsl.l d0,d2 ; Shift pos by sector size
move.w SegmentLen(a4,d5.w),d0 ; Get length of segment Move an extra segment length bytes
rol.w #8,d0 ; Position bytes correctly
add.l d0,d2 ; Add the length
bsr SeekTo ; Goto that position
bsr ReadIntelWord ; Get length of buffer Get intel word at that address (items in table)
clr.l d3 ; Clear d0 Allocate items in table * 8 bytes of ram
move.w d2,d3 ; Get length of buffer
move.l d3,d4 ; d4=number of entries counter (x)
lsl.l #3,d3 ; Multiply by 8
move.l d3,d0 ; Save copy of length
move.l d3,RelocBufferLen(a5) ; Save permanent copy of buffer len
move.l #AnyMemoryType,d1 ; Any memory type
move.l AbsExecBase,a6 ; Get address of exec base
jsr _LVOAllocMem(a6) ; Allocate the memory
move.l DosBase(a5),a6 ; Get dos.library pointer
tst.l d0 ; Was memory allocated?
bne RelocBufferOK ; Jump if OK
lea OutOfMemMSG,a0 ; Get address of message If allocation UNsuccesful then
move.l OutOfMemMSGLen,d3 ; Get length of message Print "Out of memory"
bsr PrintMSG ; Print the message
rts ; Return rts
RelocBufferOK
move.l d0,a4 ; a4=address of reloc buffer Read items in table * 8 bytes into allocates buffer
move.l d0,RelocBufferAddr(a5) ; Keep permanent copy of buffer addr
move.l d0,d2 ; Get address of buffer
move.l aFileHandle(a5),d1 ; Get file handle
jsr _LVORead(a6) ; Get relocation table
cmp.l d0,d3 ; Check return value If read failed then
beq RelocReadOK ; Jump if ok
lea RelocReadFailedMSG,a0 ; Get address of message Print "Read from file failed"
move.l RelocReadFailedMSGLen,d3; Get length of message
RelocError
bsr PrintMSG ; Print the message
move.l HeaderAddress(a5),a4 ; Get address of header
move.l RelocBufferAddr(a5),a1 ; Get address of buffer
move.l RelocBufferLen(a5),d0 ; Get length of buffer
move.l AbsExecBase,a6 ; Get address of exec base
jsr _LVOFreeMem(a6) ; Allocate the memory
move.l DosBase(a5),a6 ; Get dos.library pointer
rts ; Finished rts
RelocReadOK
lea TypeOffsTargetMSG,a0 ; Get address of message Print "type offset target"
move.l TypeOffsTargetMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
PrintRelocItem ; FOR x = 1 to items in table
move.l #NULL,d0 ; Clear new signal Test for CTRL_C
move.l d0,d1 ; Clear signal mask
move.l AbsExecBase,a6 ; Get exec base
jsr _LVOSetSignal(a6) ; Get signals
and.l #SIGBREAKF_CTRL_C,d0 ; Test for CTRL_C
bne Escape ; Jump if pressed
move.l DosBase(a5),a6 ; Get dos.library base
lea LoByteMSG,a0 ; Get address of message If RelocAddrType = 0 then
move.l LoByteMSGLen,d3 ; Get length of message Print "LoByte "
cmp.b #0,RelocAddrType(a4) ; Is it = 0?
beq RelocTypeFound ; Print reloc type
lea SelectMSG,a0 ; Get address of message If RelocAddrType = 2 then
move.l SelectMSGLen,d3 ; Get length of message Print "Select "
cmp.b #2,RelocAddrType(a4) ; Is it = 2?
beq RelocTypeFound ; Print reloc type
lea PtrMSG,a0 ; Get address of message If RelocAddrType = 3 then
move.l PtrMSGLen,d3 ; Get length of message Print "PTR "
cmp.b #3,RelocAddrType(a4) ; Is it = 3?
beq RelocTypeFound ; Print reloc type
lea OffsMSG,a0 ; Get address of message If RelocAddrType = 5 then
move.l OffsMSGLen,d3 ; Get length of message Print "OFFS "
cmp.b #5,RelocAddrType(a4) ; Is it = 5?
beq RelocTypeFound ; Print reloc type
lea Ptr48MSG,a0 ; Get address of message If RelocAddrType = 11 then
move.l Ptr48MSGLen,d3 ; Get length of message Print "PTR-48 "
cmp.b #11,RelocAddrType(a4) ; Is it = 11?
beq RelocTypeFound ; Print reloc type
lea Offs32MSG,a0 ; Get address of message If RelocAddrType = 13 then
move.l Offs32MSGLen,d3 ; Get length of message Print "OFFS-32 "
cmp.b #13,RelocAddrType(a4) ; Is it = 13?
beq RelocTypeFound ; Print reloc type
lea RelocTypeUnknMSG,a0 ; Get address of message else print "Unknown relocation type. Send me this file to df114@city.ac.uk read docs!!!!"
move.l RelocTypeUnknMSGLen,d3 ; Get length of message
bra RelocError ; Finish rts
RelocTypeFound
bsr PrintMSG ; Print reloc type
lea RelocOffset(a4),a3 ; Get address of reloc offset Print RelocOffset
bsr PrePrintSingleIntelWord ; Prepare for printing
subq.l #1,d3 ; No newline
bsr PrintMSG ; Print the number
lea SixBlankSpacesMSG,a0 ; Get address of message
move.l SixBlankSpacesMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
tst.b RelocType(a4) ; Is it 0 If RelocType = 0 then Internal reference
beq RelocInternalReference ; Jump if true
cmp.b #1,RelocType(a4) ; Is it 1 If RelocType = 1 then Imported ordinal
beq RelocImportedOrdinal ; Jump if true
cmp.b #2,RelocType(a4) ; Is it 2 If RelocType = 2 then Imported name
beq RelocImportedName ; Jump if true
cmp.b #3,RelocType(a4) ; Is it 3 If RelocType = 3 then OSFIXUP
beq RelocOSFIXUP ; Jump if true
cmp.b #5,RelocType(a4) ; Is it 5 If RelocType = 5 then Additive?
beq RelocAdditive ; Jump if true
lea RelocTypeUnknMSG,a0 ; Get address of message else
move.l RelocTypeUnknMSGEnd,d3 ; Get length of message Print "Unknown relocation type send me this file to df114@city.ac.uk read docs!!!!"
bra RelocError ; Finish rts
RelocInternalReference ; If RelocType = 0 then Internal reference
cmp.b #$FF,RelocB4(a4) ; Is segment movable? If RelocB4 = $FF then
bne RelocInternalFixed ; Jump if fixed segment
lea EntryMSG,a0 ; Get address of message Print "Entry "
move.l EntryMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
lea RelocB6(a4),a3 ; Get pointer to entry ,RelocB6
bsr PrePrintSingleIntelWord ; Print the number
bra RelocItemPrinted ; Done
RelocInternalFixed
move.l RelocB4(a4),d0 ; Get number else
swap d0 ; Swap register halves Print RelocB4,":",RelocB6 Segment:Offset are the wrong way round
rol.w #8,d0 ; Position bytes correctly
swap d0 ; Swap register halves
rol.w #8,d0 ; Form number correctly
bsr PrintMotoRegNum ; Print the number
bra RelocItemPrinted ; Done
RelocImportedOrdinal ; If RelocType = 1 then
move.l HeaderAddress(a5),a3 ; Get address of header
clr.l d0 ; Clear d0
move.l d0,d1 ; Clear d1
move.b RelocB4(a4),d0 ; Get RelocB4 (RelocB4 - 1)*2
subq.b #1,d0 ; RelocB4-1
lsl.w #1,d0 ; (RelocB4-1)*2
move.w ModRefOffset(a3),d1 ; Get offset to mod-ref table Add offset to mod-ref table
rol.w #8,d1 ; Position bytes correctly
add.l d0,d1 ; Add numbers
move.w (a3,d1),d1 ; Get offset into imp-nam table
rol.w #8,d1 ; Position bytes correctly
move.w ImpNameOffset(a3),d0 ; Get offset to imp-nam table Add that word to offset of imp-name table
rol.w #8,d0 ; Position bytes correctly
add.l d0,d1 ; Add the numbers
lea (a3,d1),a0 ; Get address of string Print that byte many bytes at that addr+1
move.b (a0)+,d3 ; Get length of string
bsr PrintMSG ; Print the string
lea FullStopMSG,a0 ; Get address of message Print "."
move.l FullStopMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
lea RelocB6(a4),a3 ; Get address of number ,RelocB6
bsr PrePrintSingleIntelWord ; Prepare for printing
bsr PrintMSG ; Print the number
bra RelocItemPrinted ; Done
RelocImportedName ; If RelocType = 2 then ; Imported name
move.l HeaderAddress(a5),a3 ; Get address of header
clr.l d0 ; Clear d0
move.l d0,d1 ; Clear d1
move.b RelocB4(a4),d0 ; Get RelocB4 (RelocB4 - 1)*2
subq.b #1,d0 ; RelocB4-1
lsl.w #1,d0 ; (RelocB4-1)*2
move.w ModRefOffset(a3),d1 ; Get offset to mod-ref table Add offset to mod-ref table
rol.w #8,d1 ; Position bytes correctly
add.l d0,d1 ; Add numbers
move.w (a3,d1),d1 ; Get offset into imp-nam table
rol.w #8,d1 ; Position bytes correctly
move.w ImpNameOffset(a3),d0 ; Get offset to imp-nam table Add that word to offset of imp-name table
rol.w #8,d0 ; Position bytes correctly
add.l d0,d1 ; Add the numbers
lea (a3,d1),a0 ; Get address of string Print that byte many bytes at that addr+1
move.b (a0)+,d3 ; Get length of string
bsr PrintMSG ; Print the string
lea FullStopMSG,a0 ; Get address of message Print "."
move.l FullStopMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
move.l HeaderAddress(a5),a3 ; Get address of header
clr.l d0 ; Clear d0
move.l d0,d1 ; Clear d1
move.b RelocB6(a4),d0 ; Get RelocB6 RelocB6 + offset to imp-name table
move.w ImpNameOffset(a3),d1 ; Get offset to imp-nam table
rol.w #8,d1 ; Position bytes correctly
add.l d0,d1 ; Add the numbers
lea (a3,d1),a0 ; Get address of string Print that byte many bytes at that addr+1
move.b (a0)+,d3 ; Get length of string
bsr PrintMSG ; Print the string
lea NewLineMSG,a0 ; Get address of message
move.l NewLineMSG,d3 ; Get length of message
bsr PrintMSG ; Print the message
bra RelocItemPrinted ; Done
RelocOSFIXUP ; If RelocType = 3 then OSFIXUP
lea RelocTypeUnknMSG,a0 ; Get address of message Print "OSFIXUP Send me this file to df114@city.ac.uk read docs!!!!"
move.l RelocTypeUnknMSGLen,d3 ; Get length of message
bra RelocError ; Finished rts
RelocAdditive
move.l HeaderAddress(a5),a3 ; Get address of header
clr.l d0 ; Clear d0
move.l d0,d1 ; Clear d1
move.b RelocB4(a4),d0 ; Get RelocB4 (RelocB4 - 1)*2
subq.b #1,d0 ; RelocB4-1
lsl.w #1,d0 ; (RelocB4-1)*2
move.w ModRefOffset(a3),d1 ; Get offset to mod-ref table Add offset to mod-ref table
rol.w #8,d1 ; Position bytes correctly
add.l d0,d1 ; Add numbers
move.w (a3,d1),d1 ; Get offset into imp-nam table
rol.w #8,d1 ; Position bytes correctly
move.w ImpNameOffset(a3),d0 ; Get offset to imp-nam table Add that word to offset of imp-name table
rol.w #8,d0 ; Position bytes correctly
add.l d0,d1 ; Add the numbers
lea (a3,d1),a0 ; Get address of string Print that byte many bytes at that addr+1
move.b (a0)+,d3 ; Get length of string
bsr PrintMSG ; Print the string
lea FullStopMSG,a0 ; Get address of message Print "."
move.l FullStopMSGLen,d3 ; Get length of message
bsr PrintMSG ; Print the message
lea RelocB6(a4),a3 ; Get address of number ,RelocB6
bsr PrePrintSingleIntelWord ; Prepare for printing
bsr PrintMSG ; Print the number
RelocItemPrinted
addq.l #8,a4 ; Add 8 Add 8 to pointer ; Skip to next entry in relocation table
subq.w #1,d4 ; Decrement num of entries
tst.w d4
bne PrintRelocItem ; Loop END ; FOR
move.l RelocBufferAddr(a5),a1 ; Get address of reloc buffer Deallocate memory just used
move.l RelocBufferLen(a5),d0 ; Get length of reloc buffer
move.l AbsExecBase,a6 ; Get exec base
jsr _LVOFreeMem(a6) ; Free the memory
move.l DosBase(a5),a6 ; Restore dos.library pointer
move.l HeaderAddress(a5),a4 ; Get address of header
NoRelocInThisSeg
addq.w #8,d5 ; Add 8 to pointer Add 8 to pointer' ; Skip to next entry in segment table
addq.w #1,d7 ; Increment segment counter
subq.w #1,d6 ; Decrement number of segments
tst.w d6 ; Are we finished?
bne SearchSegTab4Reloc ; Loop END ; FOR
rts ; Finished
Escape
move.l RelocBufferAddr(a5),a1 ; Get address of reloc buffer Deallocate memory just used
move.l RelocBufferLen(a5),d0 ; Get length of reloc buffer
jsr _LVOFreeMem(a6) ; Free the memory
move.l DosBase(a5),a6 ; Restore dos.library pointer
move.l HeaderAddress(a5),a4 ; Get address of header
UserBreakHere
lea UserBreakMSG,a0 ; Get address of message Print user break message
move.l UserBreakMSGLen,d3 ; Get length of message
bra PrintMSG ; Print the message Quit
*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
**
** PrintByte PrintByte(Number)
** d3
**
** Print the byte held in d3
**
**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
PrintByte
lea TempBuffer(a5),a0 ; Get address of temp buffer
bsr ConvertBin2ASCII ; Convert number to ASCII
move.b #"$",(a0) ; Put a $ sign
move.b d0,1(a0) ; Put high nibble
move.b d1,2(a0) ; Put low nibble
move.l #3,d3 ; Three characters to print
bra PrintMSG ; Print the number
**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
**
** PrintMotoRegNum PrintMotoRegNum(Number)
** d0
**
** Prints the normal format number in d0 in segment:offset form
**
**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
PrintMotoRegNum
rol.w #8,d0 ; Convert to intel form
swap d0 ; Swap register halves
rol.w #8,d0 ; Convert to intel form
move.l d0,StackEquation(a5) ; Put number for printing
lea StackEquation(a5),a3 ; Get address of number
bra PrintSegOffset ; Print the number
**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
**
** PrintSegOffset PrintSegOffset(*Number)
** a3
**
** Prints a segment and offset number as pointed to by a3
**
**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
PrintSegOffset
lea TempBuffer(a5),a1 ; Get address of printing buffer
move.l a1,a0 ; Make a copy of buffer address
move.b #"$",(a1)+ ; Put $ for hexadecimal
addq.l #2,a3 ; Bump pointer to segment number
bsr PrePrintIntelWord ; Print the segment number
move.b #":",(a1)+ ; Character in between seg and offset
subq.l #4,a3 ; Bump pointer back to offset
bsr PrePrintIntelWord ; Print the offset number
move.b #NewLine,(a1)+ ; New line
move.l #11,d3 ; Length of string
bra PrintMSG ; Print string
**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
**
** PrePrintIntelWord PrePrintIntelWord(*Number,*PrintBuffer)
** a3 a1
**
** Puts the ASCII codes for a word into a string ready to be printed. a3 points to the number and
** a1 points to the number itself in Intel format.
**
**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
PrePrintIntelWord
move.b 1(a3),d3 ; Get high byte of number
bsr ConvertBin2ASCII ; Get ASCII codes
move.b d0,(a1)+ ; Put high nibble
move.b d1,(a1)+ ; Put low nibble
move.b (a3),d3 ; Get low byte of number
bsr ConvertBin2ASCII ; Get ASCII codes
move.b d0,(a1)+ ; Put high nibble
move.b d1,(a1)+ ; Put low nibble
addq.l #2,a3 ; Increment pointer past number
rts ; Return
**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
**
** PrePrintSingleIntelWord *Buffer , Length = PrePrintSingleIntelWord(*Number)
** a0 d3 a3
**
** Prepares a single Intel format word for printing. It return a pointer to the print buffer and has
** the length in d3 ready for a call to PrintMSG.
**
**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
PrePrintSingleIntelWord
lea TempBuffer(a5),a1 ; Get address of temporary buffer
move.l a1,a0 ; Keep a temporary copy of buffer address
move.b #"$",(a1)+ ; Put $ for hex number
bsr PrePrintIntelWord ; Put number
move.b #NewLine,(a1)+ ; Put new line character
move.l #6,d3 ; 6 characters to be printed
rts ; Finished
**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
**
** ReadIntelWord d2 = ReadIntelWord
**
** Read an Intel backward format word from current position in file and
** returns it as a proper Motorola word
**
**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ReadIntelWord
move.l aFileHandle(a5),d1 ; Get file handle
lea TempBuffer(a5),a0 ; Get address of temp buffer
move.l a0,d2 ; Put temp buffer address in d2
move.l #2,d3 ; Two bytes or word to be checked
jsr _LVORead(a6) ; Read word for checking
cmp.l #2,d0 ; Read OK?
bne ReadFailed ; Goto read failed error
move.w TempBuffer(a5),d2 ; Get word
rol.w #8,d2 ; Swap high and low byte
rts ; Return word
**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
**
** SeekTo SeekTo(Position)
** d2
**
** Seeks to the indicated position in the file. If operation unsuccesful
** the return address is POPed from the stack and an error printed.
**
**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
SeekTo
move.l aFileHandle(a5),d1 ; Move file handle to d1
move.l #OFFSET_BEGINNING,d3 ; Seek from beginning of file
jsr _LVOSeek(a6) ; Seek
cmp.l #-1,d0 ; Was seek succesful?
beq SeekNotSuccesful ; Goto error if unsuccesful
rts ; Completed succesfully
**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
**
** ConvertBin2ASCII d0,d1 = ConvertBin2ASCII (binary number)
** d3
**
** Converts an 8-digit binary number to two ASCII hexadecimal digits.
**
** d0 = high digit bits 4-7
** d1 = low digit bits 0-3
**
**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ConvertBin2ASCII
move.b d3,d0 ; Get low nibble
and.b #$0F,d0 ; Blank out high nibble
bsr ConvertNumber ; Convert the nibble
move.b d0,d1 ; Store low nibble in d1
move.b d3,d0 ; Get high nibble
lsr.b #4,d0 ; Position it correctly
ConvertNumber
add.b #$30,d0 ; Add ASCII "0"
cmp.b #$3A,d0 ; Is number < 10 ?
blt ConversionComplete ; If yes then conversion complete
add.b #$07,d0 ; Add to ASCII "A"
ConversionComplete
rts ; Conversion completed
**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
**
** PrintMSG PrintMSG (*MSG,Length)
** a0 d3
**
** Prints a given message to standard out.
**
**+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
PrintMSG
move.l DosBase(a5),a6 ; Get dos base address
move.l a0,d2 ; Put message pointer in d2
move.l OutputHandle(a5),d1 ; Move output handle to d1
jsr _LVOWrite(a6) ; Print message
rts ; Print complete
**=====================================================================================================
**
** Error handlers
**
**=====================================================================================================
FileNotOpenOK
move.l FileNotOpenMSGLen,d3 ; Get length of message
lea FileNotOpenMSG,a0 ; Get pointer to error message
bra PrintErrorAndReturnToDos; Print error message
MemoryNotAllocated
move.l MemoryNotAllocatedMSGLen,d3 ; Get length message
lea MemoryNotAllocatedMSG,a0 ; Get pointer to error message
bra CloseFileAndDosLibPrintMSG ; Print error message
NotWindowsEXE
move.l NotWindowsEXEMSGLen,d3 ; Get length message
lea NotWindowsEXEMSG,a0 ; Get pointer to error message
bra CloseFileAndDosLibPrintMSG ; Print error message
ReadFailed
move.l ReadFailedMSGLen,d3 ; Get length message
lea ReadFailedMSG,a0 ; Get pointer to error message
addq.l #4,sp ; POP return address from stack
bra CloseFileAndDosLibPrintMSG ; Print error message
SeekNotSuccesful
move.l SeekNotSuccesMSGLen,d3 ; Get length message
lea SeekNotSuccesMSG,a0 ; Get pointer to error message
addq.l #4,sp ; POP return address from stack
bra CloseFileAndDosLibPrintMSG ; Print error message
CloseFileAndDosLibPrintMSG
move.l a0,a3 ; Save message pointer
move.l aFileHandle(a5),d1 ; Get file handle
move.l DosBase(a5),a6 ; Get dos lib base address
jsr _LVOClose(a6) ; Close file
move.l a3,a0 ; Get message pointer
PrintErrorAndReturnToDos
bsr PrintMSG ; Print error message
tst.l UseStdIOFlag(a5) ; Using stdio?
bne UsingStdIOAlso ; Jump if yes
move.l #SIGBREAKF_CTRL_C,d0 ; Test CTRL C Test for CTRL_C
move.l AbsExecBase,a6 ; Get exec.library base
jsr _LVOWait(a6) ; Wait signal
move.l DosBase(a5),a6 ; Get dos.library base
move.l OutputHandle(a5),d1 ; Get handle for output Close our own output channel
jsr _LVOClose(a6) ; Close it
UsingStdIOAlso
move.l a6,a1 ; Pointer to dos.library Close dos.library
move.l AbsExecBase,a6 ; Get exec base address
jsr _LVOCloseLibrary(a6) ; Close dos.library
move.l a5,a1 ; Free temporary storage memory Deallocate temp buffer
move.l TempBufferLen(a5),d0 ; Get length of temporary buffer
jsr _LVOFreeMem(a6) ; Free the memory
moveq.l #0,d0 ; Return code = 0
rts ; Return to DOS
DosNotOpen
move.l a5,a1 ; Free temporary storage memory
move.l TempBufferLen(a5),d0 ; Get size of memory block
jsr _LVOFreeMem(a6) ; Free the memory
move.l #20,d0 ; Error code = 20 not open
rts ; Exit
TempBufNoAlloc
move.l #30,d0 ; Error code = 30 buffer not allocated
rts ; Exit
**=====================================================================================================
**
** The wonderful data section
**
**=====================================================================================================
SECTION data,DATA
DosLibName
dc.b "dos.library",NULL
FileName
dc.b "TaskMan.exe",NULL
** Error messages
FileNotOpenMSGLen
dc.l FileNotOpenMSGEnd-FileNotOpenMSG
FinishMSGLen
dc.l FinishMSGEnd-FinishMSG
MemoryNotAllocatedMSGLen
dc.l MemoryNotAllocatedMSGEnd-MemoryNotAllocatedMSG
NotWindowsEXEMSGLen
dc.l NotWindowsEXEMSGEnd-NotWindowsEXEMSG
ReadFailedMSGLen
dc.l ReadFailedMSGEnd-ReadFailedMSG
SeekNotSuccesMSGLen
dc.l SeekNotSuccesMSGEnd-SeekNotSuccesMSG
FileNotOpenMSG
dc.b "File did not open succesfully.",NewLine
FileNotOpenMSGEnd
FinishMSG
dc.b NewLine,"Program completed succesfully.",NewLine
FinishMSGEnd
MemoryNotAllocatedMSG
dc.b "Memory not allocated, not enough memory perhaps?",NewLine,NULL
MemoryNotAllocatedMSGEnd
NotWindowsEXEMSG
dc.b "This is not a windows NE file.",NewLine
NotWindowsEXEMSGEnd
ReadFailedMSG
dc.b "Read operation failed.",NewLine
ReadFailedMSGEnd
SeekNotSuccesMSG
dc.b "Seek operation unsuccesful",NewLine
SeekNotSuccesMSGEnd
** Data printing messages
AccessTypeMSGLen
dc.l AccessTypeMSGEnd-AccessTypeMSG
AutoDataSegMSGLen
dc.l AutoDataSegMSGEnd-AutoDataSegMSG
CodeMSGLen
dc.l CodeMSGEnd-CodeMSG
DataMSGLen
dc.l DataMSGEnd-DataMSG
EntryMSGLen
dc.l EntryMSGEnd-EntryMSG
EntryConstantMSGLen
dc.l EntryConstantMSGEnd-EntryConstantMSG
EntryEntriesMSGLen
dc.l EntryEntriesMSGEnd-EntryEntriesMSG
EntryEntriesSegMSGLen
dc.l EntryEntriesSegMSGEnd-EntryEntriesSegMSG
EntryExportedMSGLen
dc.l EntryExportedMSGEnd-EntryExportedMSG
EntryFixOffsetMSGLen
dc.l EntryFixOffsetMSGEnd-EntryFixOffsetMSG
EntryFixSegRecrMSGLen
dc.l EntryFixSegRecrMSGEnd-EntryFixSegRecrMSG
EntryMoveOffsetMSGLen
dc.l EntryMoveOffsetMSGEnd-EntryMoveOffsetMSG
EntryMoveRecrMSGLen
dc.l EntryMoveRecrMSGEnd-EntryMoveRecrMSG
EntryMoveSegMSGLen
dc.l EntryMoveSegMSGEnd-EntryMoveSegMSG
EntryNullEntriesMSGLen
dc.l EntryNullEntriesMSGEnd-EntryNullEntriesMSG
EntryNumberMSGLen
dc.l EntryNumberMSGEnd-EntryNumberMSG
EntryTableMSGLen
dc.l EntryTableMSGEnd-EntryTableMSG
ExecutableTypeMSGLen
dc.l ExecutableTypeMSGEnd-ExecutableTypeMSG
ExecuteOnlyMSGLen
dc.l ExecuteOnlyMSGEnd-ExecuteOnlyMSG
FileDataModelMSGLen
dc.l FileDataModelMSGEnd-FileDataModelMSG
FileSegLengthMSGLen
dc.l FileSegLengthMSGEnd-FileSegLengthMSG
FixedMSGLen
dc.l FixedMSGEnd-FixedMSG
FullStopMSGLen
dc.l FullStopMSGEnd-FullStopMSG
GlobalMSGLen
dc.l GlobalMSGEnd-GlobalMSG
InitCSIPMSGLen
dc.l InitCSIPMSGEnd-InitCSIPMSG
InitLocalHeapMSGLen
dc.l InitLocalHeapMSGEnd-InitLocalHeapMSG
InitStackSizeMSGLen
dc.l InitStackSizeMSGEnd-InitStackSizeMSG
IsSelfLoadingMSGLen
dc.l IsSelfLoadingMSGEnd-IsSelfLoadingMSG
LibraryModuleMSGLen
dc.l LibraryModuleMSGEnd-LibraryModuleMSG
LoaderAllocMSGLen
dc.l LoaderAllocMSGEnd-LoaderAllocMSG
LoadOnCallMSGLen
dc.l LoadOnCallMSGEnd-LoadOnCallMSG
LoByteMSGLen
dc.l LoByteMSGEnd-LoByteMSG
MinAllocForSegMSGLen
dc.l MinAllocForSegMSGEnd-MinAllocForSegMSG
ModTableEntriesMSGLen
dc.l ModTableEntriesMSGEnd-ModTableEntriesMSG
ModuleDescribeMSGLen
dc.l ModuleDescribeMSGEnd-ModuleDescribeMSG
ModuleNameMSGLen
dc.l ModuleNameMSGEnd-ModuleNameMSG
MoveableMSGLen
dc.l MoveableMSGEnd-MoveableMSG
MultipleDataModelMSGLen
dc.l MultipleDataModelMSGEnd-MultipleDataModelMSG
NewLineMSGLen
dc.l NewLineMSGEnd-NewLineMSG
NoMSGLen
dc.l NoMSGEnd-NoMSG
NoAutoDataModelMSGLen
dc.l NoAutoDataModelMSGEnd-NoAutoDataModelMSG
NoDataInSegmentMSGLen
dc.l NoDataInSegmentMSGEnd-NoDataInSegmentMSG
NoLocalHeapMSGLen
dc.l NoLocalHeapMSGEnd-NoLocalHeapMSG
NonResNamTableMSGLen
dc.l NonResNamTableMSGEnd-NonResNamTableMSG
NonShareMSGLen
dc.l NonShareMSGEnd-NonShareMSG
NormalExecutableMSGLen
dc.l NormalExecutableMSGEnd-NormalExecutableMSG
OffsMSGLen
dc.l OffsMSGEnd-OffsMSG
Offs32MSGLen
dc.l Offs32MSGEnd-Offs32MSG
OutOfMemMSGLen
dc.l OutOfMemMSGEnd-OutOfMemMSG
PreLoadMSGLen
dc.l PreLoadMSGEnd-PreLoadMSG
PrintRelocationMSGLen
dc.l PrintRelocationMSGEnd-PrintRelocationMSG
PtrMSGLen
dc.l PtrMSGEnd-PtrMSG
Ptr48MSGLen
dc.l Ptr48MSGEnd-Ptr48MSG
ReadOnlyMSGLen
dc.l ReadOnlyMSGEnd-ReadOnlyMSG
RelocForSegMSGLen
dc.l RelocForSegMSGEnd-RelocForSegMSG
RelocReadFailedMSGLen
dc.l RelocReadFailedMSGEnd-RelocReadFailedMSG
RelocTypeUnknMSGLen
dc.l RelocTypeUnknMSGEnd-RelocTypeUnknMSG
ResNamTableMSGLen
dc.l ResNamTableMSGEnd-ResNamTableMSG
ResourceTypeMSGLen
dc.l ResourceTypeMSGEnd-ResourceTypeMSG
RevisionNumMSGLen
dc.l RevisionNumMSGEnd-RevisionNumMSG
rnFlagsMSGLen
dc.l rnFlagsMSGEnd-rnFlagsMSG
rnFlagsMoveableMSGLen
dc.l rnFlagsMoveableMSGEnd-rnFlagsMoveableMSG
rnFlagsPreloadMSGLen
dc.l rnFlagsPreloadMSGEnd-rnFlagsPreloadMSG
rnFlagsPureMSGLen
dc.l rnFlagsPureMSGEnd-rnFlagsPureMSG
rnIDMSGLen
dc.l rnIDMSGEnd-rnIDMSG
rnOffsetMSGLen
dc.l rnOffsetMSGEnd-rnOffsetMSG
rnLengthMSGLen
dc.l rnLengthMSGEnd-rnLengthMSG
rscAlignShiftMSGLen
dc.l rscAlignShiftMSGEnd-rscAlignShiftMSG
RscTableOffsetMSGLen
dc.l RscTableOffsetMSGEnd-RscTableOffsetMSG
RT_AcceleratorMSGLen
dc.l RT_AcceleratorMSGEnd-RT_AcceleratorMSG
RT_BitmapMSGLen
dc.l RT_BitmapMSGEnd-RT_BitmapMSG
RT_CursorMSGLen
dc.l RT_CursorMSGEnd-RT_CursorMSG
RT_DialogMSGLen
dc.l RT_DialogMSGEnd-RT_DialogMSG
RT_FontMSGLen
dc.l RT_FontMSGEnd-RT_FontMSG
RT_FontDirMSGLen
dc.l RT_FontDirMSGEnd-RT_FontDirMSG
RT_Group_CursorMSGLen
dc.l RT_Group_CursorMSGEnd-RT_Group_CursorMSG
RT_Group_IconMSGLen
dc.l RT_Group_IconMSGEnd-RT_Group_IconMSG
RT_IconMSGLen
dc.l RT_IconMSGEnd-RT_IconMSG
RT_MenuMSGLen
dc.l RT_MenuMSGEnd-RT_MenuMSG
RT_RCDataMSGLen
dc.l RT_RCDataMSGEnd-RT_RCDataMSG
RT_StringMSGLen
dc.l RT_StringMSGEnd-RT_StringMSG
RT_UnkRscTypeMSGLen
dc.l RT_UnkRscTypeMSGEnd-RT_UnkRscTypeMSG
RT_VersionInfoMSGLen
dc.l RT_VersionInfoMSGEnd-RT_VersionInfoMSG
rtResourceCountMSGLen
dc.l rtResourceCountMSGEnd-rtResourceCountMSG
SegDiscardMSGLen
dc.l SegDiscardMSGEnd-SegDiscardMSG
SegmentLoadedMSGLen
dc.l SegmentLoadedMSGEnd-SegmentLoadedMSG
SegmentLoadTypeMSGLen
dc.l SegmentLoadTypeMSGEnd-SegmentLoadTypeMSG
SegmentNumberMSGLen
dc.l SegmentNumberMSGEnd-SegmentNumberMSG
SegmentTypeMSGLen
dc.l SegmentTypeMSGEnd-SegmentTypeMSG
SegmentRelocMSGLen
dc.l SegmentRelocMSGEnd-SegmentRelocMSG
SegmentSharingMSGLen
dc.l SegmentSharingMSGEnd-SegmentSharingMSG
SegRelocationMSGLen
dc.l SegRelocationMSGEnd-SegRelocationMSG
SegTableEntryNumMSGLen
dc.l SegTableEntryNumMSGEnd-SegTableEntryNumMSG
SegTableOffsetMSGLen
dc.l SegTableOffsetMSGEnd-SegTableOffsetMSG
SelectMSGLen
dc.l SelectMSGEnd-SelectMSG
ShareMSGLen
dc.l ShareMSGEnd-ShareMSG
SingleDataModelMSGLen
dc.l SingleDataModelMSGEnd-SingleDataModelMSG
SixBlankSpacesMSGLen
dc.l SixBlankSpacesMSGEnd-SixBlankSpacesMSG
SixtyFourKMSGLen
dc.l SixtyFourKMSGEnd-SixtyFourKMSG
StackAddressMSGLen
dc.l StackAddressMSGEnd-StackAddressMSG
TypeOffsTargetMSGLen
dc.l TypeOffsTargetMSGEnd-TypeOffsTargetMSG
UserBreakMSGLen
dc.l UserBreakMSGEnd-UserBreakMSG
VersionNumMSGLen
dc.l VersionNumMSGEnd-VersionNumMSG
YesMSGLen
dc.l YesMSGEnd-YesMSG
TemplateLen
dc.l TemplateEnd-Template
AccessTypeMSG
dc.b " Access type : "
AccessTypeMSGEnd
AutoDataSegMSG
dc.b "Automatic data segment number : "
AutoDataSegMSGEnd
CodeMSG
dc.b " CODE"
CodeMSGEnd
DataMSG
dc.b " DATA"
DataMSGEnd
EntryMSG
dc.b "Entry "
EntryMSGEnd
EntryConstantMSG
dc.b NewLine,"Constant bundle : "
EntryConstantMSGEnd
EntryEntriesMSG
dc.b " entries.",NewLine
EntryEntriesMSGEnd
EntryEntriesSegMSG
dc.b " entries. Segment : "
EntryEntriesSegMSGEnd
EntryExportedMSG
dc.b " Exported "
EntryExportedMSGEnd
EntryFixOffsetMSG
dc.b " Offset : "
EntryFixOffsetMSGEnd
EntryFixSegRecrMSG
dc.b NewLine,"Fixed segment records : "
EntryFixSegRecrMSGEnd
EntryMoveOffsetMSG
dc.b " Offset : "
EntryMoveOffsetMSGEnd
EntryMoveRecrMSG
dc.b NewLine,"Movable segment records : "
EntryMoveRecrMSGEnd
EntryMoveSegMSG
dc.b " Segment : "
EntryMoveSegMSGEnd
EntryNullEntriesMSG
dc.b NewLine,"Null entries : "
EntryNullEntriesMSGEnd
EntryNumberMSG
dc.b NewLine," Entry "
EntryNumberMSGEnd
EntryTableMSG
dc.b NewLine,"Entry table : ",NewLine
EntryTableMSGEnd
ExecutableTypeMSG
dc.b "Executable type : "
ExecutableTypeMSGEnd
ExecuteOnlyMSG
dc.b " EXECUTEONLY"
ExecuteOnlyMSGEnd
FileDataModelMSG
dc.b "Data model type : "
FileDataModelMSGEnd
FileSegLengthMSG
dc.b " Segment length in file : "
FileSegLengthMSGEnd
FixedMSG
dc.b " FIXED"
FixedMSGEnd
FullStopMSG
dc.b "."
FullStopMSGEnd
GlobalMSG
dc.b "GLOBAL",NewLine
GlobalMSGEnd
InitCSIPMSG
dc.b "Initial CS:IP : "
InitCSIPMSGEnd
InitLocalHeapMSG
dc.b "Initial local heap size : "
InitLocalHeapMSGEnd
InitStackSizeMSG
dc.b "Initial stack size : "
InitStackSizeMSGEnd
IsSelfLoadingMSG
dc.b "Self loading application? : "
IsSelfLoadingMSGEnd
LibraryModuleMSG
dc.b "Library module",NewLine
LibraryModuleMSGEnd
LoaderAllocMSG
dc.b "Loader allocates memory for segment.",NewLine
LoaderAllocMSGEnd
LoadOnCallMSG
dc.b " LOADONCALL"
LoadOnCallMSGEnd
LoByteMSG
dc.b " LoByte "
LoByteMSGEnd
MinAllocForSegMSG
dc.b " Minimum allocation for segment : "
MinAllocForSegMSGEnd
ModuleDescribeMSG
dc.b NewLine,"Module description : "
ModuleDescribeMSGEnd
ModuleNameMSG
dc.b NewLine,"Module name : "
ModuleNameMSGEnd
ModTableEntriesMSG
dc.b "Entries in module reference table : "
ModTableEntriesMSGEnd
MoveableMSG
dc.b " MOVEABLE"
MoveableMSGEnd
MultipleDataModelMSG
dc.b "MULTIPLEDATA",NewLine
MultipleDataModelMSGEnd
NewLineMSG
dc.b NewLine
NewLineMSGEnd
NoMSG
dc.b "NO",NewLine
NoMSGEnd
NoAutoDataModelMSG
dc.b "NOAUTODATA",NewLine
NoAutoDataModelMSGEnd
NoDataInSegmentMSG
dc.b "No data provided for this segment.",NewLine
NoDataInSegmentMSGEnd
NoLocalHeapMSG
dc.b "No initial allocation",NewLine
NoLocalHeapMSGEnd
NonResNamTableMSG
dc.b NewLine," Non-resident name table :",NewLine
NonResNamTableMSGEnd
NonShareMSG
dc.b " IMPURE"
NonShareMSGEnd
NormalExecutableMSG
dc.b "Normal executable",NewLine
NormalExecutableMSGEnd
OffsMSG
dc.b " Offs "
OffsMSGEnd
Offs32MSG
dc.b " Offs-32 "
Offs32MSGEnd
OutOfMemMSG
dc.b NewLine,"Out of memory.",NewLine
OutOfMemMSGEnd
PreLoadMSG
dc.b " PRELOAD"
PreLoadMSGEnd
PrintRelocationMSG
dc.b NewLine,NewLine,"Segment relocations",NewLine
PrintRelocationMSGEnd
PtrMSG
dc.b " PTR "
PtrMSGEnd
Ptr48MSG
dc.b " PTR-48 "
Ptr48MSGEnd
ReadOnlyMSG
dc.b " READONLY"
ReadOnlyMSGEnd
RelocForSegMSG
dc.b " Relocations for segment : "
RelocForSegMSGEnd
RelocReadFailedMSG
dc.b "Read from file failed!"
RelocReadFailedMSGEnd
RelocTypeUnknMSG
dc.b "Unknown relocation type. Send me this file to df114@city.ac.uk read docs!!!!"
RelocTypeUnknMSGEnd
ResNamTableMSG
dc.b NewLine," Resident-name table :",NewLine
ResNamTableMSGEnd
ResourceTypeMSG
dc.b NewLine,NewLine,NewLine," Resource type : "
ResourceTypeMSGEnd
RevisionNumMSG
dc.b "Linker revision number : "
RevisionNumMSGEnd
rnFlagsMSG
dc.b " Resource attributes",NewLine
rnFlagsMSGEnd
rnFlagsMoveableMSG
dc.b " MOVEABLE"
rnFlagsMoveableMSGEnd
rnFlagsPreloadMSG
dc.b " PRELOAD "
rnFlagsPreloadMSGEnd
rnFlagsPureMSG
dc.b " PURE"
rnFlagsPureMSGEnd
rnIDMSG
dc.b NewLine," Resource ID : "
rnIDMSGEnd
rnLengthMSG
dc.b " Resource length : "
rnLengthMSGEnd
rnOffsetMSG
dc.b NewLine," Resource offset : "
rnOffsetMSGEnd
rscAlignShiftMSG
dc.b "Resource align shift : "
rscAlignShiftMSGEnd
RscTableOffsetMSG
dc.b NewLine,"Offset to resource table : "
RscTableOffsetMSGEnd
RT_AcceleratorMSG
dc.b "RT_ACCELERATOR",NewLine
RT_AcceleratorMSGEnd
RT_BitmapMSG
dc.b "RT_BITMAP",NewLine
RT_BitmapMSGEnd
RT_CursorMSG
dc.b "RT_CURSOR",NewLine
RT_CursorMSGEnd
RT_DialogMSG
dc.b "RT_DIALOG",NewLine
RT_DialogMSGEnd
RT_FontMSG
dc.b "RT_FONT",NewLine
RT_FontMSGEnd
RT_FontDirMSG
dc.b "RT_FONTDIR",NewLine
RT_FontDirMSGEnd
RT_Group_CursorMSG
dc.b "RT_GROUP_CURSOR",NewLine
RT_Group_CursorMSGEnd
RT_Group_IconMSG
dc.b "RT_GROUP_ICON",NewLine
RT_Group_IconMSGEnd
RT_IconMSG
dc.b "RT_ICON",NewLine
RT_IconMSGEnd
RT_MenuMSG
dc.b "RT_MENU",NewLine
RT_MenuMSGEnd
RT_RCDataMSG
dc.b "RT_RCDATA",NewLine
RT_RCDataMSGEnd
RT_StringMSG
dc.b "RT_STRING",NewLine
RT_StringMSGEnd
RT_UnkRscTypeMSG
dc.b "Unknown resource type "
RT_UnkRscTypeMSGEnd
RT_VersionInfoMSG
dc.b "Version info?",NewLine
RT_VersionInfoMSGEnd
rtResourceCountMSG
dc.b " Resource count : "
rtResourceCountMSGEnd
SegDiscardMSG
dc.b " DISCARDABLE"
SegDiscardMSGEnd
SegmentLoadedMSG
dc.b "Segment is loaded at load time."
SegmentLoadedMSGEnd
SegmentLoadTypeMSG
dc.b " Segment loaded type : "
SegmentLoadTypeMSGEnd
SegmentNumberMSG
dc.b NewLine,NewLine,"Data for segment number : "
SegmentNumberMSGEnd
SegmentRelocMSG
dc.b " Segment relocation : "
SegmentRelocMSGEnd
SegmentSharingMSG
dc.b " Segment sharing : "
SegmentSharingMSGEnd
SegmentTypeMSG
dc.b " Segment flags:",NewLine
SegmentTypeMSGEnd
SegRelocationMSG
dc.b " RELOCATIONS"
SegRelocationMSGEnd
SegTableEntryNumMSG
dc.b "Entries in segment table : "
SegTableEntryNumMSGEnd
SegTableOffsetMSG
dc.b "Offset to segment table : "
SegTableOffsetMSGEnd
SelectMSG
dc.b " Select "
SelectMSGEnd
ShareMSG
dc.b " PURE"
ShareMSGEnd
SingleDataModelMSG
dc.b "SINGLEDATA",NewLine
SingleDataModelMSGEnd
SixBlankSpacesMSG
dc.b " "
SixBlankSpacesMSGEnd
SixtyFourKMSG
dc.b "64k",NewLine
SixtyFourKMSGEnd
StackAddressMSG
dc.b "Initial SS:SP : "
StackAddressMSGEnd
TypeOffsTargetMSG
dc.b " type offset target",NewLine
TypeOffsTargetMSGEnd
UserBreakMSG
dc.b NewLine,NewLine,"User break!",NewLine,NewLine
UserBreakMSGEnd
VersionNumMSG
dc.b NewLine,"Linker version number : "
VersionNumMSGEnd
YesMSG
dc.b "YES",NewLine
YesMSGEnd
Template
dc.b "Name/A,STDIO/S"
TemplateEnd
dc.b NULL ; do *NOT* remove! Part of template
OutputString
dc.b "CON:0/10/640/100/Soyeb is the best",0
END